我们如何在多款产品中通过环境隔离限制Claude的爆炸半径
我们如何在多款产品中限制Claude
十二个月前,我们还会断然拒绝授予Claude足以攻破内部Anthropic服务的访问权限。如今,这种级别的访问已是家常便饭,Anthropic的开发者也因此效率倍增。这类部署的风险包含两个部分:故障发生的可能性,以及可能造成的损害程度。防护措施和模型训练的进步稳步降低了前者;而后者——理论上的爆炸半径——只会随着能力和访问权限的扩展而增长。然而,当代理变得能够完成曾经需要一个人甚至一个团队才能完成的工作时,不部署的代价变得如此之大,以至于只要产品能够确保安全,风险回报的计算就严重倾向于采用。工程问题变成了如何限制爆炸半径。
当自主代理的相对损害可以被限定——例如通过控制其环境——高实用性能力便可以推动部署。Claude Mythos Preview 是一个典型案例:在2026年4月,其爆炸半径被认为过高而无法发布。然而,随着防御者加固关键系统、防护措施趋于成熟,我们预计具有类似能力水平的模型将更适合广泛发布——尽管某些风险将始终存在。模型能力是代理部署总风险中的一个重要因素。
限制爆炸半径大致有两种方法。
第一种是通过人机回环来监督代理的行为。Claude Code 此前通过要求用户在每个环节给予许可,来保护代理免受意外操作的影响。理论上这行得通,但我们发现这种方法存在缺陷。我们的遥测数据显示,用户批准了大约93%的许可提示。用户看到的批准越多,对每个提示的注意力就越少,久而久之监督的勤勉程度大大降低。我们最近构建了 Claude Code 自动模式,通过自动化更安全的批准来减少这种批准疲劳。尽管如此,漏洞仍然存在——任何概率性防御都有非零的漏报率。(1)
第二种限制爆炸半径的方法——也是本文重点——是环境隔离。与其监督代理做什么,我们通过强制访问边界来监督它能做什么,例如通过沙箱、虚拟机和出口控制。这是Anthropic工程投入最多的地方,也是许多最令人惊讶的安全故障发生之处。
在过去两年里,我们发布了三款主要的代理产品:claude.ai、Claude Code 和 Claude Cowork。每款产品面向不同受众,需要不同的隔离架构。本文分享这些架构中哪些经住了考验、哪些出了问题,以及我们在此过程中学到的关于代理安全的知识。
三类风险,三部分防御
代理面临的安全风险分为三类:
* 用户误用: 用户——无论出于恶意还是粗心——引导代理做出有害行为。这包括从要求代理绕过他们认为烦人的检查,到运行他们不理解的有破坏性命令,再到指定故意危害。 * 模型行为不当: 代理在无人要求的情况下采取了有害行动。随着模型改进,它们在大多数行为评估上变得更加一致,但这并不意味着风险必然缩小。能力较弱的模型更容易误判情况并犯明显错误。能力更强的模型犯的错更少,但它们也更擅长找到通往目标的意外路径,通常是通过绕过没人想到要写下的限制。在Anthropic,我们曾看到Claude模型为了完成任务而“好心”地逃出沙箱、检查git历史来寻找编码测试的答案、以及自发识别它正在其上运行的基准测试以便解密答案密钥。每个模型都带来一套新能力,有时会被以意想不到的方式利用。 * 外部攻击者: 代理通过外部向量受到攻击,例如工具、文件或网络访问。这一类别既包括提示注入,也包括针对代理运行时、编排层或代理的传统攻击。
在构建隔离和防御系统时,我们对三个主要组件应用防御:
1. 代理运行的环境。 我们通过进程沙箱、虚拟机、文件系统边界和出口控制来限制代理能够行动的地点和方式。目标是设置一个代理能够触及的硬边界。例如,如果凭据从未进入沙箱,那么无论原因是用户、模型找到“创造性”路径还是攻击者,它们都无法被窃取。紧密的边界也意味着您可以放松监督。Claude Code 的参考 devcontainer 的存在正是为了让代理可以在无需逐操作批准的情况下无人值守运行。 2. 代理咨询的模型。 这里的机制包括系统提示、分类器、探针和训练修改。由于模型是概率性的,这些机制只塑造代理倾向于做什么,而不是理论上能做什么。这些防御很强大。在Gray Swan的代理红队基准测试中(测试对提示注入的敏感性),Claude Opus 4.7 在单次尝试中的攻击成功率大约为0.1%,在100次自适应尝试后约为5-6%。Claude Code 自动模式在执行前能捕获大约83%的过度积极行为。然而,即使拥有最佳的防御,模型层的保护也永远不会100%有效,这就是为什么它不能单独存在。 3. 代理能够达到的外部内容。 MCP服务器、第三方插件和网络搜索工具都会将来自您无法控制的源的内容输入代理的上下文。经过审计的连接器不等于审计过的数据——例如,一个GitHub连接器可以将被污染的README直接加载到模型的上下文中,尽管通过了恶意软件检查。精细限制工具权限有助于限制爆炸半径。例如,具有只读数据库访问权限的代理可以比写入生产环境的代理更广泛地部署。
防御措施应该重叠并相互补充。当环境防御不可用时,模型层必须填补空缺(这正是Claude Code自动模式的设计目的)。在本地,环境和模型防御可以防范恶意工具输出,但通过在更高层限制工具的能力和访问权限,可以添加防御。
限制代理的隔离模式
聚焦于环境层,我们描述三种隔离模式以及它们如何针对每个Claude平台——claude.ai、Claude Code 和 Cowork——进行定制。我们逐渐达到了每种设计,在代理所需能力与用户所需干预程度之间找到了平衡。
模式1:临时容器(claude.ai代码执行)
尽管以聊天界面闻名,claude.ai 也编写和运行代码、生成文件以及调用连接器。当Claude在claude.ai内部运行代码时,它在一个gVisor容器内运行在隔离的基础设施上。代理完全在服务器端;没有代码在本地机器上运行,文件系统是临时的(每个会话)。爆炸半径很小,但Claude能做的事情的上限也很小——没有持久的工作空间,也无法访问用户的文件系统。
这也使claude.ai承受更传统的威胁模型。我们不是在保护用户机器免受代理侵害;而是在保护我们自己的基础设施和每个租户彼此隔离。我们为claude.ai进行的发布前工作主要围绕传统安全工作,如网络配置、内部服务认证和编排。
这些工作强化了安全中最古老的教训:最薄弱的层是你自己构建的那一层。gVisor和seccomp在对抗资源充足的攻击者方面已经比代理人工智能存在的时间久得多,因此审查工作投入到我们围绕它们构建的较新部分。我们稍后会回到这一点,因为我们自定义的代理也是我们最重要事件中出问题的部分。
模式2:人机回环沙箱(Claude Code)
Claude Code 在用户机器上运行,可以访问用户的文件系统、shell和网络。没有这些,编码代理的实用性就会受限,因此必须找到安全授予这种访问权限的方法。
一种方法是依赖人机回环。这只对Claude Code来说是一个可行的解决方案,因为普通用户是熟悉编码环境的开发者:他们能读bash,他们知道rm -rf的作用,而且他们每周都会从不受信任的源运行npm install几次。所有这些意味着,当弹出“允许此操作”对话框时,他们极有可能具备准确评估代理试图做什么以及相关风险的专业知识。鉴于此,Claude Code 以最简单的防御启动:允许读取,要求批准写入、bash和网络访问。
然而,如前所述,批准疲劳在几周内就出现了。讽刺的是,这意味着原本旨在提供监督的功能可能产生相反效果——某些用户可能干脆不再注意。作为缓解不谨慎批准的第一步,我们发布了一个操作系统级沙箱(macOS上为Seatbelt,Linux上为bubblewrap),它加固了边界:允许读取,允许在工作空间内写入,但默认拒绝网络。在沙箱内,代理基本上可以在不间断的情况下运行。结果是批准提示减少了84%,并且我们开源了运行时,因此边界可审计。
我们的匿名使用数据还显示,有经验的用户自动批准的频率大约是新手的两倍,但他们也更多地在中途中断代理的执行。有经验的用户不是逐步骤把关,而是更可能在代理偏离轨道时才进行监督。虽然这可能是人们偏好与代理合作的自然演变,但这种方法也有缺陷,需要用户足够技术和专注,以便首先注意到偏离。随着模型能力提升,代理开始编写越来越有野心的bash,检测这种偏离也变得更加困难。而且,随着用户转向多代理系统,这种方法也不太可能成为有效的监督策略。
我们错过的风险:信任对话框之前的一切
在2025年中至2026年1月期间,我们通过负责任的披露计划收到了Claude Code中的漏洞报告。其中三个漏洞针对的是在用户同意任何内容之前执行的代码。要了解这是如何可能的,考虑最直接的情况:一个开发者克隆了一个仓库来审查拉取请求,该仓库包含一个.claude/settings.json,其中定义了一个钩子。由于Claude Code在启动期间读取项目设置——在显示标准的“您信任此文件夹吗?”提示之前——攻击者编写并提交的钩子会自动执行。其余案例在结构上类似,其中来自尚未信任目录的输入在信任边界建立之前就被解析了。
每个案例的修复方法具有相同模式:将项目本地配置的解析和执行推迟到用户接受信任提示之后。如果您正在构建类似的东西,请将项目打开、配置加载和localhost侦听器视为来自互联网的任何入站请求。它们不应仅仅因为感觉是本地的且在用户同意之前到达就被隐式信任。
我们错过的风险:用户作为注入向量
2026年2月,在一次受控的内部红队演习中,一名研究员成功通过钓鱼使一名员工启动Claude Code并附带一个恶意提示。钓鱼看起来像普通的协作——一封“你能帮我运行这个吗?”的电子邮件,附带一个随时可粘贴的提示——该提示本身读起来像常规任务指令。但在某些设置步骤中间,它温和地要求Claude读取~/.aws/credentials,对内容进行编码,并通过POST发送到外部端点。在25次该提示的重试中,Claude完成了24次数据窃取。
这是一种直接提示注入——攻击者的指令通过用户到达,而不是通过工具输出或获取的内容。我们的模型层防御锚定在用户意图上——当用户是输入指令的人时,分类器没有任何异常可捕获。一个人类承包商拿着同样的脚本也会做同样的事情。
这种情况下唯一有效的防御是环境,具体来说是阻止POST的出口控制(无论意图如何),以及首先将~/.aws置于不可达范围的文件系统边界。
(当我们在内部Slack中分享这个有效的提示进行讨论时,有人指出一些内部代理会阅读Slack。载荷现在已经出现在环境中。我们在线程中添加了一个金丝雀字符串,以便如果任何东西拾取它,我们能注意到。在一个代理阅读一切的世界里,调查工具本身也是一个攻击面。)
模式3:本地虚拟机(Claude Cowork)
Claude Cowork 在用户桌面上运行,可以访问用户选择的工作空间文件夹。由于该平台是为一般知识工作而非软件工程构建的,普通用户不太可能精通bash。
因此,人机回环沙箱策略可能不适用;不应期望非技术知识工作者能够判断像find . -name "*.tmp" -exec rm {} \;这样的bash咒语。当批准一个例外需要典型用户不具备的专业知识时,管理员应该设置一个绝对且始终开启的边界。
为了实现这一点,我们的第一个Claude Cowork版本使用平台的供应商管理程序(macOS上为Apple的Virtualization框架,Windows上为HCS)运行在完整的虚拟机内部。虚拟机有自己的Linux内核、文件系统和进程表。用户选择的工作空间和.claude文件夹被挂载;主机上其他内容不可见。凭据保留在主机钥匙串中,永远不会进入客户机。这种设计防止了Claude在某个时刻以不对齐的方式行事的可能性。被损害的Claude仍然可能破坏工作空间文件夹内的内容,因此架构设计确保这是它能触及的唯一东西(直到用户添加连接器),并且用户控制那里挂载了什么。
在最初的架构中——我们称之为全虚拟机模式——代理循环本身运行在客户机内部,因此Claude作为一个普通的Linux用户执行,不知道它被沙箱化了。相比之下,Claude Code中有一个特权进程位于沙箱外部,决定每个命令是否强制执行沙箱;一个有说服力的注入提示或一次疲劳的批准点击可以让该进程运行未沙箱化的东西。在这里,没有外部进程持有逃生舱门钥匙,因此没有组件有权授予例外。
Claude Cowork虚拟机的六种主要隔离机制。其中两种在客户机内核外部强制实施,因此即使代理在虚拟机内获得root级访问权限,它们仍然有效。其他四种由客户机强制实施,并保持刻意最小化,因为外层承担其余部分。
然而,我们很快意识到在完全虚拟机模式下运行整个代理会导致实际问题:虚拟机启动期间的任何故障都会导致Cowork无法使用。将代理循环移到虚拟机外部,同时将代码执行保留在虚拟机内部,使得Claude仍然能够回应用户并帮助调试问题,而不是在错误上冻结。这一变化造成最小的安全影响,因为虚拟机仍然对代理执行的代码实施文件系统和网络控制。
另外,我们还将本地MCP服务器移到了虚拟机外部。在虚拟机内部运行它们使审计变得困难,在虚拟机更新时造成脆弱的依赖问题,并且不支持需要与本地进程(如数据库)交互的MCP——这些服务器无论如何都必须在主机上运行。这一变化使Claude Cowork与本地MCP服务器在Claude Desktop中已有的工作方式保持一致:将它们视为用户可能选择安装的任何软件,并委托管理员决定启用哪些本地MCP(如果有的话)。远程MCP服务器不受影响,因为它们不在用户机器上运行。
将代理循环放在虚拟机内部意味着虚拟机中的任何故障都会导致Cowork无法使用。主机模式更可靠,因为如果虚拟机崩溃,代理仍然可以响应,并且通过隔离代码执行,它仍然提供重要的安全保证。
文件系统控制是另一个重要的架构选择。Claude需要能够访问主机上的某些文件才能有用,但我们希望最小化爆炸半径,并向用户提供关于本地文件访问的透明度。我们发现提供不同的文件挂载模式有助于精细控制风险;Claude Cowork 提供只读、读写和读写不删除三种模式。一个潜在的陷阱是符号链接解析必须在路径验证之前进行,而不是之后,否则授权文件夹内的符号链接可能指向外部并逃脱。对于企业客户,我们允许管理员通过MDM设置中的挂载路径允许列表来控制这一点。
我们错过的风险:通过批准的域进行数据窃取
一个通过批准的域进行数据窃取的明显例子来自第三方披露。Claude Cowork 的出口允许列表正确放行了到api.anthropic.com的流量——产品无法在不调用我们自己API的情况下运行。在这个例子中,用户挂载的工作空间中放置了一个恶意文件,其中包含隐藏指令以及攻击者控制的API密钥。Claude 遵循指令,读取工作空间中的其他文件,并使用攻击者的密钥调用Anthropic的文件API。出口代理检查了目的地,看到api.anthropic.com,就放行了。文件被上传到攻击者的Anthropic账户。沙箱运行完美,然而数据却被窃取了。
此前,我们将允许列表概念化为一个目的地过滤器,告诉Claude这些域可以与之通信。但更好的概念化可能是一个能力授权。允许列表上任何域可访问的每个功能现在都是一个攻击面。允许api.anthropic.com意味着允许向任意Anthropic账户上传文件。
我们通过一个位于虚拟机内部的防御性中间人代理来修复它,该代理拦截到我们API的流量。它只传递携带虚拟机自身配置的会话令牌的请求;攻击者嵌入的密钥会被代理拒绝。它还阻止可能启用服务器端获取的头。代理位于虚拟机内部而不是我们的服务器上,因为只有虚拟机知道来源——从服务器的角度来看,Cowork请求与任何其他API客户端无法区分。
上图:到api.anthropic.com的流量被放行,导致数据泄露。下图:修复方案:在虚拟机内部部署一个中间人代理,拦截到我们API的流量。
这也是我们自己构建的软件往往是最弱环节原则的第二个实例。我们产品中的管理程序、seccomp和gVisor一直可靠。我们自定义的允许列表代理是出问题的部分。
我们错过的风险:虚拟机隔离也将端点检测软件拒之门外
在评估Claude Cowork时,企业安全团队问:“为什么我们的端点检测和响应看不见内部?”答案是,同样的隔离让Claude被限制,也让基于主机的端点检测和响应无法进入。从端点检测和响应的角度来看,Claude Cowork 是一个不透明的管理程序进程。它无法检查客户机。
隔离降低了可见性,对于依赖端点可见性来满足合规要求的团队来说,不透明性是个问题。我们当前的缓解措施是使用基于拉取的OTLP导出,让管理员事后检索事件日志,但这与实时监控不同。如果您正在构建类似的东西,请尽早为这个对话做好预算。
| 环境 | 临时容器 (claude.ai) | 人机回环沙箱 (Claude Code) | 密封虚拟机 (Claude Cowork) | |------|----------------------|---------------------------|--------------------------| | 成本:隔离开销 | 容器启动时间短 | 低延迟原生沙箱 | 完整的虚拟机启动 | | 成本:用户依赖 | 无 | 必须能解释bash | 无 | | 风险:爆炸半径 | 服务器端容器(由gVisor+主机基础设施边界防护) | 本地工作空间 | 挂载的工作空间(由vsock+管理程序边界防护) |
信任代理读取的内容
企业经常问我们如何保护MCP连接。这是个好问题,但正确的问题比MCP更广泛。提供给代理的任何外部资源同时代表两种风险:传统供应链意义上的代码执行风险,以及提示注入向量。传统的依赖审计(固定版本、验证签名、审查源代码)解决了前者,但忽略了后者。
远程与本地之间的区别比看起来更重要。本地安装的工具是可审计的。你可以阅读代码、固定版本,并知道它不会在你下面改变。远程工具——托管的MCP服务器、云连接器——在你批准后可能随时改变行为;你安装时的信任决定可能不再适用。我们的连接器目录通过持续审查来解决这个问题,但目录之外的任何内容都应被视为不受信任。先针对假数据运行它,放在恶意工具的爆炸半径已被控制的环境中。
即使工具受信任,工具输出也是一个攻击面。前面提到的GitHub README例子正是这种情况;应用于网页的任何输入扫描都需要以同样严格的方式应用于启用网络的工具结果。尽管这会增加延迟并且不是完美的防御,我们倾向于实时检查:一旦被毒化的工具返回已经引导代理进入窃取数据,日志只会显示一个成功的、授权的API调用。没有事后信号可供发现。
在Claude Code和Claude Cowork中,工具调用通过强制执行网络和文件策略的代理,并且可以在返回值进入模型上下文之前检查它们。进行检查的分类器可以是一个小而快的模型;它不需要是进行推理的那个模型。
展望未来
模型和产品正在快速发展。随着它们的进步,风险也在演变和进化,我们的缓解措施必须跟上步伐。
* 持久内存中毒。 跨会话持久存在的代理上下文比例不断增长——包括产品记忆、CLAUDE.md文件、挂载的工作空间,以及定时和长期运行代理的状态目录。落在这其中任何一处的注入在每次代理启动时都会被重新加载。随着更多代理状态在会话中存活,我们受到经典后利用意义上新持久性机制的威胁。启动时的良好分类器将需要变得更加普遍。
* 多代理信任升级。 一方面,子代理可以隔离不受信任的内容,将结构化事实而非原始文本返回给主代理。另一方面,这可能会被滥用:如果子代理的输出被视为比原始工具结果更值得信任,因为该输出来自“我们”,那么就会引入一个新的提示注入向量。在多代理系统中,分配不同信任级别与容易遭受信任升级之间存在权衡。
* 代理身份。 Claude Cowork 对代理身份的答案很具体:凭据保留在主机钥匙串中,虚拟机获得一个按会话缩小的令牌,该令牌可以独立于用户令牌被撤销。然而,我们开始应对跨平台代理身份的更广泛问题。代理应该拥有自己的主体身份,还是应该作为用户的扩展并继承用户的权限?最终,答案可能是两者的混合。
随着代理能力的增强,攻击面在不断变化。我们看到的故障类型很可能在行业和实验室中重复出现。我们需要集体投资于代理特定的安全态势,从共享基准和披露规范到共同身份标准和跨供应商红队。本文我们关注隔离,但这只是代理安全图景的一部分。关于治理、可观测性和其余内容,请参阅NIST关于AI代理身份和授权的项目、由澳大利亚ACSC与美国CISA和英国NCSC领导的六机构关于采用代理人工智能的指导,以及ISO/IEC 42001人工智能管理标准。我们的Glasswing计划是一个贡献,但我们期待与合作伙伴和竞争对手共同应对这个关键问题。
总结
简而言之,我们反复回到以下几个原则:
1. 首先在环境层设计隔离,然后在模型层引导行为。 让我们学得最多的两起事件——员工钓鱼和第三方允许列表披露——都是出口泄露的情况,其中数据通过被允许的路径离开。在每种情况下,模型层都无能为力;没有异常供它捕捉。确定性边界是当所有概率性手段都失手时起作用的屏障。 2. 将隔离强度与用户的监督能力相匹配。 能读bash的开发者与不能读的知识工作者运行的不是同一个威胁模型。用户是否有能力评估代理即将做什么的问题应该有助于确定隔离策略,在任何方向上答错——给专家太多摩擦,给非专家太多信任——本身就是一个失败。 3. 小心自定义组件。 经过实战考验的管理程序、系统调用过滤器和容器运行时比你构建的任何东西经受住了更多的对抗性关注。在本文描述的每个部署中,标准原语都保持稳定,而我们围绕它们构建的自有部分暴露了缺陷。
最终,虽然代理可能是一类新的软件,但它们的系统级交互并非如此。它们仍然读取文件、打开套接字和生成进程;这使得使用成熟工具进行隔离成为一个至关重要的可行防御。部署的风险回报平衡将随着AI的发展而不断变化,但对爆炸半径设置硬限制往往能将这种平衡推向正确的方向。
致谢
作者:Max McGuinness, Mikaela Grace, Jiri De Jonghe, Jake Eaton, 和 Abel Ribbink。
我们还感谢 Hanah Ho, Hasnain Lakhani, Pedram Navid, Molly Villagra, Maya Nielan, Akila Srinivasan, Travis Szucs, Sam Attard, Alfred Xing, Mohamad El Hajj, Gabby Curtis, David Dworken, Adam Jones, Amie Rotherham, Christian Ryan, Lucas Smedley, Brett Andrews 及其他人的贡献。
特别感谢我们的安全和产品工程团队,以及报告Claude产品漏洞的个人和组织。
脚注
(1) Claude Code自动模式将命令审批委托给基于模型的分类器;它以牺牲一小部分风险命令为代价(大约0.4%的良性命令被阻止),最小化了摩擦(大约17%的过度积极操作得以通过),因此它是沙箱内深度防御的一层,而不是替代沙箱。