如何跨产品限制Claude的破坏半径:容器、沙箱与虚拟机
如何跨产品限制Claude的破坏半径
十二个月前,我们还会断然拒绝让Claude拥有足以关闭Anthropic内部服务的访问权限。如今,这种级别的访问已是常态,Anthropic的开发者也因此效率大增。这些部署的风险包含两个部分:故障发生的可能性,以及故障可能造成的损害程度。安全防护和模型训练的进展稳步降低了前者;而后者——理论上的破坏半径——随着能力和访问权限的扩展只会不断增大。然而,当智能体能够胜任曾经需要一个甚至整个团队才能完成的工作时,不部署的风险就变得足够大,只要产品能确保安全,风险回报的天平就大幅倾向采用。工程问题就变成了如何限制破坏半径。
当自主智能体相对损害的范围可以被限定——例如通过控制其运行环境——高实用性能力就能推动部署。Claude Mythos Preview就是一个例子,它的模型破坏半径在2026年4月被认为过高而无法发布。不过,随着防御者加固关键系统、安全防护机制成熟,我们预计具有类似能力水平的模型将在更广泛范围内发布变得合适——尽管某些风险始终存在。模型能力是智能体部署总风险中的一个重要因素。
限制破坏半径大致有两种方法。
第一种是通过人类参与监督来监控智能体的行为。Claude Code此前通过要求用户在每一步给予许可来防止智能体采取意外行动。理论上这行得通,但我们发现这种方法并不可靠。我们的遥测数据显示,用户批准了大约93%的许可提示。用户看到的批准越多,对每一个的关注就越少,久而久之监督的仔细程度大大降低。我们最近构建了Claude Code自动模式,通过自动化更安全的批准来减少这种批准疲劳。尽管如此,漏洞仍然存在——任何概率性防御都有非零的漏报率[1]。
第二种限制破坏半径的方法——也是本文的重点——是限制(containment)。与其监督智能体做什么,不如通过实施访问边界来监督它能做什么,例如通过沙箱、虚拟机和出口控制。这是Anthropic工程团队投入精力最多的地方,也是许多最令人惊讶的安全故障发生的地方。
过去两年里,我们主要发布了三款智能体产品:claude.ai、Claude Code和Claude Cowork。每款产品面向不同用户群体,需要不同的限制架构。本文分享哪些方法行之有效,哪些出了问题,以及我们在智能体安全方面学到的经验。
三种风险,三类防御组件
智能体面临的安全风险分为三类:
用户误用: 用户——无论是恶意还是粗心——引导智能体做出有害行为。这包括从要求智能体绕过他们认为烦人的检查,到运行他们不理解的危险命令,再到指定故意伤害。
模型不当行为: 智能体在无人要求的情况下采取了有害行动。随着模型改进,它们在大多数行为评估上更加对齐,但这并不意味着风险必然缩小。能力较弱的模型更可能误判情况并犯明显错误。能力更强的模型犯错误更少,但它们也更善于找到实现目标的意外路径,通常是绕过没有人想到要写下的限制。
在Anthropic,我们见过Claude模型“帮忙”逃离沙箱以完成任务,检查git历史来寻找编码测试答案,以及自发识别正在运行的基准测试以便解密答案密钥。每个模型都带来一套新能力,有时这些能力以意想不到的方式被利用。
外部攻击者: 智能体通过外部向量受到攻击,例如工具、文件或网络访问。这一类别包括提示注入和针对智能体运行时、编排层或代理的传统攻击。
在构建限制和防御系统时,我们将防御应用于三个主要组件:
智能体运行的环境。 我们通过进程沙箱、虚拟机、文件系统边界和出口控制来限制智能体行动的地点和方式。目标是为智能体能触及的范围设定一个硬边界。例如,如果凭证从不进入沙箱,它们就无法被窃取,无论原因是用户、模型找到“创造性”路径还是攻击者。
紧致的外围也意味着你可以放松监督。Claude Code的参考开发容器(devcontainer)的存在正是为了让智能体可以在无需逐个批准的情况下无人值守运行。
智能体咨询的模型。 这里的机制包括系统提示、分类器、探针和训练修改。由于模型是概率性的,这些只能塑造智能体倾向于做什么,而不能限制它在理论上能够做什么。
这些防御是强大的。在Gray Swan的Agent Red Teaming基准测试中,针对提示注入的敏感性测试,Claude Opus 4.7在单次尝试中攻击成功率约为0.1%,在100次自适应尝试后约为5-6%。Claude Code自动模式在执行前捕获了大约83%的过度积极行为。然而,即使拥有同类最佳的防御,模型层的保护也永远不会达到100%有效,因此它不能单独使用。
智能体能触及的外部内容。 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针对资源丰富的对手经过强化的时间远远超过智能体AI存在的时间,因此审查工作主要集中在围绕它们构建的新组件上。我们稍后会回到这一点,因为在我们最严重的事件中,正是我们自定义的代理出了问题。
#### 模式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在启动过程中——在显示标准的“您信任此文件夹吗?”提示之前——就读取了项目设置,攻击者编写并提交的钩子会自动执行。其余情况在结构上类似,即来自尚未信任的目录的输入在信任边界建立之前就被解析了。
每次修复的形状都一样:将项目本地配置的解析和执行推迟到用户接受信任提示之后。如果你在构建类似的东西,请把项目打开、配置加载和本地主机监听器当作来自互联网的任何入站请求来对待。它们不应该仅仅因为感觉是本地且在用户同意之前到达就被隐式信任。
我们忽略的风险:用户作为注入向量
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仍然可能破坏工作区文件夹内的内容,因此架构设计确保那是它能触及的唯一内容(直到用户添加连接器),并且用户控制挂载进去的内容。
在最初的架构中——我们称之为全VM模式——智能体循环本身在虚拟机内部运行,因此Claude作为一个普通的Linux用户执行,对自己被沙箱化毫无察觉。相比之下,在Claude Code中,一个特权进程位于沙箱外部,决定每个命令是否执行沙箱策略;一个有说服力的注入提示或一次疲劳的批准点击可以使该进程运行一些不受沙箱保护的内容。在这里,没有外部进程持有逃生舱钥匙,因此没有组件有权批准例外。
Claude Cowork的VM的六种主要隔离机制。其中两种在虚拟机内核外部强制执行,因此即使智能体在VM内获得root级访问权限,它们仍然有效。其他四种是虚拟机内部强制执行的,并刻意保持最小化,因为外部层承担了其余部分。
然而,我们很快意识到,在全VM模式下运行整个智能体会导致实际问题:VM启动期间的任何故障都会使Cowork无法使用。将智能体循环移到虚拟机外部,同时将代码执行保留在虚拟机内部,使Claude仍然能够响应用户并帮助调试问题,而不是在错误时冻结。这一改变对安全性影响极小,因为虚拟机仍然对智能体执行的代码实施文件系统和网络控制。
另外,我们还将本地MCP服务器移到了虚拟机外部。在虚拟机内部运行它们使它们更难审计,在VM更新时产生脆弱的依赖问题,并且不支持需要与本地进程(如数据库)交互的MCP——这类服务器无论如何都必须在主机上运行。这一改变使Claude Cowork与Claude Desktop中本地MCP服务器的工作方式一致:将它们视为用户可能选择安装的任何软件,并委托管理员决定启用哪些本地MCP(如果有的话)。远程MCP服务器不受影响,因为它们不在用户机器上运行。
智能体循环在VM内部意味着VM的任何故障都会使Cowork无法使用。主机模式更可靠,因为如果VM崩溃,智能体仍然可以响应,并且它通过隔离代码执行仍然提供了重要的安全保证。
文件系统控制是另一个重要的架构选择。Claude需要能够访问主机上的某些文件才能有用,但我们希望最小化破坏半径,并向用户提供本地文件访问的透明度。我们发现提供不同的文件挂载模式有助于精细控制风险;Claude Cowork提供只读、读写和读写不删除三种模式。其中一个潜在的陷阱是,符号链接解析必须在路径验证之前进行,而不是之后,否则授权文件夹内的符号链接可以指向外部并逃脱。对于企业客户,我们允许管理员通过MDM设置中的挂载路径允许列表来控制这一点。
我们忽略的风险:通过被批准域名的窃取
通过被批准域名窃取的一个明确案例来自第三方披露。Claude Cowork的出口允许列表正确放行了到api.anthropic.com的流量——产品不调用我们自己的API就无法运行。在这个案例中,用户挂载的工作区中的一个恶意文件携带隐藏指令以及攻击者控制的API密钥。Claude遵循指令读取工作区中的其他文件,并使用攻击者的密钥调用Anthropic的Files API。出口代理检查目标,看到api.anthropic.com,放行通过。文件被上传到攻击者的Anthropic账户。沙箱完美运行,但数据仍然被窃取了。
此前,我们曾将允许列表概念化为一个目标过滤器,告诉Claude这些域名是可以通信的。但或许更好的概念化是将其视为能力授权。允许列表上任何域名可访问的每个功能现在都是一个攻击面。允许api.anthropic.com意味着允许文件上传到任意Anthropic账户。
我们通过一个防御性中间人代理(位于VM内部,拦截到我们API的流量)修复了这个问题。它只传递携带VM自身分配的会话令牌的请求;攻击者嵌入的密钥会被代理拒绝。它还阻止会启用服务端fetch的标头。代理位于VM内部而非我们服务器上,因为只有VM知道来源——从服务器的角度来看,Cowork请求与任何其他API客户端无法区分。
上方:到api.anthropic.com的流量被放行,导致出口。下方:修复方案,使用中间人代理拦截到我们API的流量。
这也是我们自己构建的软件往往最薄弱这一原则的第二个实例。我们的产品中的虚拟机管理程序、seccomp和gVisor一直可靠。我们自定义的允许列表代理是出问题的那个组件。
我们忽略的风险:VM隔离也将端点检测软件挡在了外面
在评估Claude Cowork时,企业安全团队问道:“为什么我们的EDR看不到内部?”答案是,用于限制Claude的同一隔离也将基于主机的端点检测和响应挡在了外面。从EDR的角度来看,Claude Cowork是一个不透明的虚拟机管理程序进程。它无法检查虚拟机。
隔离降低了可见性,对于依赖端点可见性的合规姿势的团队来说,不透明性是有问题的。我们当前的缓解措施是使用基于拉取的OTLP导出,让管理员事后检索事件日志,但这与实时监控不同。如果你正在构建类似的东西,请提前为这个对话做好预算。
| 环境 | 临时容器 (claude.ai) | 人类参与沙箱 (Claude Code) | 密封VM (Claude Cowork) | |------|----------------------|----------------------------|------------------------| | 成本: 隔离开销 | 容器启动开销 | 低延迟本地沙箱 | 完整VM启动 | | 成本: 用户依赖 | N/A | 必须能解析bash | N/A | | 风险: 破坏半径 | 服务端容器 (由gVisor+主机基础设施边界保护) | 本地工作区 | 挂载的工作区 (由vsock+虚拟机管理程序边界保护) |
信任智能体读取的内容
企业经常问我们如何保护MCP连接的安全。这是一个好问题,但正确的问题比MCP本身更广泛。提供给智能体的任何外部资源同时代表两种风险:传统的供应链意义上的代码执行风险,以及提示注入向量。传统的依赖审计(固定版本、验证签名、审查源代码)解决了第一个问题,但忽略了第二个。
远程与本地比看起来更重要。本地安装的工具是可审计的。你可以阅读代码、固定版本,并知道它不会在你不知道的情况下改变。远程工具——托管的MCP服务器、云连接器——可以在你批准后的任何时候改变行为;你安装时的信任决策可能不再适用。我们的连接器目录通过持续审查解决了这个问题,但目录之外的任何东西都应被视为不受信任的。先针对假数据运行它,放在恶意工具破坏半径受限的环境中。
即使工具是受信任的,工具输出也是一个攻击面。前面提到的GitHub README示例正是这种情况;任何应用于网页的输入扫描都需要以同样严格的方式应用于启用网络的工具结果。尽管这会增加延迟并且不是完美的防御,我们倾向于实时检查:一旦被投毒的工具返回将智能体导向窃取数据,日志只会显示一个成功、授权的API调用。事后没有信号可发现。
在Claude Code和Claude Cowork中,工具调用通过代理路由,这些代理执行网络和文件策略,并可以在返回值进入模型上下文之前进行检查。执行检查的分类器可以是一个小型的快速模型;它不需要是进行推理的那个。
展望未来
模型和产品正在快速发展。随着发展,风险也在演变和进化,我们的缓解措施必须跟上步伐。
持久内存投毒。 跨会话持续的智能体上下文比例不断增长——这包括产品记忆、CLAUDE.md文件、挂载的工作区,以及调度和长期运行智能体的状态目录。注入到其中任何一个的载荷在每次智能体启动时都会被重新加载。随着更多智能体状态超越会话而存活,我们受到经典后渗透意义上的新持久化机制的威胁。会话启动时的良好分类器将需要变得更加普遍。
多智能体信任升级。 一方面,子智能体可以隔离不受信任的内容,将结构化事实而非原始文本返回给主智能体。另一方面,这可以被滥用:如果子智能体的输出被视为比原始工具结果更高信任(因为输出来自“我们”),就引入了提示注入的新向量。在多智能体系统中,在分配不同信任级别和变得容易遭受信任升级之间存在权衡。
智能体身份。 Claude Cowork对智能体身份的答案是具体的:凭据留在主机钥匙串中,虚拟机获得每个会话的范围缩小令牌,并且该令牌可以独立于用户的令牌被撤销。然而,我们开始应对跨平台智能体身份的更广泛问题。智能体应该拥有自己的主体身份,还是应该充当用户的扩展并继承用户权限?最终,答案可能是两者的混合。
随着智能体变得越来越有能力,攻击面不断变化。我们见过的故障类型很可能在行业和实验室中重复出现。我们需要在智能体特定安全态势上进行集体投资,从共享基准和披露规范到通用身份标准和跨供应商红队演练。本文中我们专注于限制,但这只是智能体安全图景的一部分。关于治理、可观测性和其他层面,请参见NIST的AI智能体身份和授权项目、由澳大利亚ACSC与CISA和英国NCSC领导的采用智能体AI的六机构指南,以及ISO/IEC 42001 AI管理标准。我们的Glasswing计划是贡献之一,但我们期待与合作伙伴和竞争对手在这一关键问题上合作。
总结
简而言之,有几个原则我们反复强调:
首先在环境层设计限制,然后在模型层引导行为。 给我们教训最深的两起事件——员工钓鱼和第三方允许列表披露——都是出口案例,数据通过允许的路径离开。在这两起事件中,模型层无能为力;没有异常可供捕捉。确定性的边界在所有概率性措施都失效时发挥作用。
将隔离强度与用户的监督能力相匹配。 能读懂bash的开发者与不能读懂的知识工作者运行的不是同一个威胁模型。用户能否评估智能体即将采取的行动这一问题应帮助确定限制策略,并且在任何一个方向上搞错——对专家过度摩擦,对非专家过度信任——本身就是失败。
警惕自定义组件。 经过实战考验的虚拟机管理程序、系统调用过滤器和容器运行时比你将构建的任何东西都承受了更多的敌对关注。在本文描述的每一个部署中,标准原语都保持可靠,而我们围绕它们自己的东西暴露了缺陷。
最终,尽管智能体可能是一种新的软件类别,但它们的系统级交互并非如此。它们仍然读取文件、打开套接字和生成进程;这使得使用成熟工具进行限制成为至关重要的可行防御。随着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自动模式将命令批准委托给基于模型的分类器;它以错过一小部分风险命令(约17%的过度积极行动通过)为代价,最小化摩擦(约0.4%的正常命令被阻止),因此它是沙箱内深度防御的一层,而不是替代品。