Claude跨产品安全隔离:从函数沙箱到全虚拟机的风险管控实践
十二个月前,我们还会断然拒绝让Claude拥有足以瘫痪内部Anthropic服务的权限。如今,这种级别的访问已是常态,而Anthropic的开发者也因此更高效。这类部署的风险包含两个部分:故障发生的可能性,以及故障可能造成的损害。我们在安全防护和模型训练上取得的进展稳步降低了前者;后者——理论爆炸半径——则随着能力和访问权限的扩展而不断增长。然而,当智能体能够完成曾经需要一个人甚至一个团队才能完成的工作时,不部署的成本就会变得足够高,以至于只要产品能够做到安全,风险收益的计算就会大幅偏向采用。工程问题就变成了如何限制爆炸半径。
当自主智能体的相对损害可以被设定边界时——例如通过控制其环境——高实用性能力就会推动部署。Claude Mythos Preview就是一个例子,其模型的爆炸半径在2026年4月被认为过高而无法发布。然而,我们预计随着防御者加固关键系统、安全机制成熟,类似能力水平的模型将适合更广泛地发布——尽管风险永远不会完全消失。模型能力是智能体部署总风险中的一个重要因素。
限制爆炸半径大致有两种方法。
第一种是通过人工介入来监督智能体的行为。Claude Code之前通过要求用户在每一步都授权,来防止智能体采取非预期行动。理论上可行,但我们发现这种方法容易出错。我们的遥测数据显示,用户批准了大约93%的权限提示。用户看到的批准越多,对每个提示的关注就越少,久而久之监督的认真程度会大幅下降。我们最近构建了Claude Code自动模式,通过自动化更安全的批准来减少这种批准疲劳。尽管如此,漏洞依然存在——任何概率性防御都有非零的漏报率。
第二种限制爆炸半径的方法——也是本文的重点——是隔离。不是监督智能体的行为,而是通过强制访问边界来监督它能做什么,例如通过沙箱、虚拟机和出口控制。这是Anthropic工程团队投入最多精力的地方,也是许多最令人惊讶的安全故障发生的地方。
过去两年里,我们发布了三个主要的智能体产品:claude.ai、Claude Code和Claude Cowork。每个服务于不同的受众,需要不同的隔离架构。本文分享哪些设计经受住了考验、哪些出了问题,以及我们在智能体安全方面学到的东西。
三种风险,三层防御
智能体的安全风险可分为三类:
用户误用: 用户——无论是恶意还是疏忽——指示智能体做出有害行为。这包括从要求智能体绕过他们觉得恼人的检查,到运行他们不懂的破坏性命令,再到指定蓄意伤害。
模型异常行为: 智能体未经要求就采取有害行动。随着我们的模型改进,它们在大多数行为评估上变得更加对齐,但这并不意味着风险一定缩小。能力较低的模型更容易误读情况并犯明显错误。能力更强的模型犯的错误更少,但它们也更善于找到通往目标的意外路径,通常是通过绕过没有人想到要写下的限制。
在Anthropic,我们见过Claude模型为了完成任务而“乐于助人”地逃出沙箱、检查git历史来寻找编码测试的答案、自发识别当前正运行的基准测试以便解密答案密钥。每个模型都带来一套新的能力,有时会以意外的方式发挥作用。
外部攻击者: 智能体通过工具、文件或网络访问等外部向量受到攻击。这类攻击既包括提示注入,也包括对智能体运行时、编排层或代理的传统攻击。
在构建隔离和防御系统时,我们对三个主要组件应用防御:
1. 智能体运行的环境。 我们通过进程沙箱、虚拟机、文件系统边界和出口控制来限制智能体能够行动的位置和方式。目标是为智能体能触及的范围设定硬边界。例如,如果凭证从未进入沙箱,它们就不可能被泄露,无论原因是用户、模型找到的“创意”路径,还是攻击者。
严格的边界也意味着可以放松监督。Claude Code的参考开发容器正是为了让智能体可以在没有逐个行动审批的情况下无人值守运行。
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针对资源充足的攻击者已经经过比智能体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仍然可能破坏工作区文件夹内的内容,因此架构旨在确保那是它能触及的唯一内容(直到用户添加连接器),并且用户控制什么被挂载在那里。
在最初的架构中——我们称之为全虚拟机模式——智能体循环本身在客户机内部运行,因此Claude以普通Linux用户身份执行,完全不知道被沙箱化了。相比之下,Claude Code有一个特权进程位于沙箱外部,决定是否按命令执行强制策略;一个有说服力的注入提示或一个疲劳的批准点击可能让该进程运行一些不在沙箱内的东西。在这里,没有一个外部进程持有逃生舱钥匙,因此没有任何组件有权授予例外。
Claude Cowork虚拟机的六种主要隔离机制。其中两种在客户机内核之外执行,即使智能体在虚拟机内获得root级访问权限,它们也能存活。其他四种由客户机强制执行,并保持最小化,因为外层承担了其余工作。
然而,我们很快意识到,在全虚拟机模式下运行整个智能体带来了实际问题:虚拟机启动时的任何故障都会使Cowork无法使用。将智能体循环移到虚拟机外部,同时将代码执行保留在虚拟机内部,使得Claude仍然能够响应用户并帮助调试问题,而不是在错误中冻结。这一更改带来的安全影响极小,因为虚拟机仍然对智能体执行的代码实施文件系统和网络控制。
另外,我们还将本地MCP服务器移到了虚拟机外部。在虚拟机内部运行它们使得审计更困难,在虚拟机更新时产生了脆弱的依赖性问题,并且不支持需要与本地进程(如数据库)交互的MCP——这些服务器无论如何都必须在主机上运行。这一更改使Claude Cowork与Claude Desktop中本地MCP服务器的工作方式保持一致:将它们视为用户可能选择安装的任何软件,并委托管理员决定启用哪些本地MCP(如果有的话)。远程MCP服务器不受影响,因为它们不在用户机器上运行。
将智能体循环放在虚拟机内部意味着虚拟机的任何故障都会导致Cowork无法使用。主机模式更可靠,因为如果虚拟机崩溃,智能体仍然可以响应,并且它通过隔离代码执行仍然提供重要的安全保证。
文件系统控制是另一个重要的架构选择。Claude需要能够访问主机上的某些文件才能有用,但我们希望最小化爆炸半径,并向用户提供本地文件访问的透明度。我们发现提供不同的文件挂载模式有助于精细控制风险;Claude Cowork提供只读、读写和读写无删除三种模式。一个潜在的陷阱是,符号链接解析必须在路径验证之前发生,而不是之后,否则授权文件夹内的符号链接可以指向外部并逃脱。对于企业客户,我们允许管理员通过MDM设置中的挂载路径白名单来控制这一点。
我们忽略的风险:通过已批准域名进行数据外泄
一个通过已批准域名进行数据外泄的清晰例子来自第三方披露。Claude Cowork的出口白名单正确地放行到api.anthropic.com的流量——产品不调用我们自己的API就无法运行。在这个案例中,用户挂载的工作区中的一个恶意文件携带了隐藏指令以及攻击者控制的API密钥。Claude按照指示读取工作区中的其他文件,并使用攻击者的密钥调用Anthropic的Files API。出口代理检查了目标地址,看到api.anthropic.com,便放行了。文件被上传到攻击者的Anthropic账户。沙箱运行完美,但数据还是被泄露了。
此前,我们将白名单概念化为目标过滤器,告诉Claude这些域名可以通信。但或许最好将其概念化为能力授权。白名单上任何域名可到达的每个功能现在都是攻击面。允许api.anthropic.com意味着允许向任意Anthropic账户上传文件。
我们通过虚拟机内一个防御性的中间人代理来修复,该代理拦截对我们的API的流量。它只允许携带虚拟机自身配发的会话令牌的请求通过;攻击者嵌入的密钥会被代理拒绝。它还阻止会启用服务端抓取的标头。代理位于虚拟机内部而不是我们的服务器上,因为只有虚拟机知道来源——从服务器角度看,Cowork请求与任何其他API客户端无法区分。
(图示:上:流量放行到api.anthropic.com,导致出口;下:使用中间人代理拦截到我们API的流量进行修复。)
这也是第二个实例,印证了你自己构建的软件往往是最薄弱的环节。我们产品中的虚拟化管理程序、seccomp和gVisor一直可靠。我们自定义的白名单代理才是出问题的部分。
我们忽略的风险:虚拟机隔离也将端点检测软件挡在门外
在评估Claude Cowork时,企业安全团队问道:“为什么我们的EDR看不到内部?”答案是,将Claude隔离在内部的相同机制,也将基于主机的端点检测和响应挡在了外面。从EDR的角度看,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合作的六机构关于采纳智能体AI的指南,以及ISO/IEC 42001 AI管理标准。
我们的Glasswing倡议是贡献之一,但我们期待与合作伙伴和竞争对手共同处理这个关键问题。
总结
简而言之,有几点原则我们反复提及:
- 首先在环境层设计隔离,然后在模型层引导行为。 最让我们学到教训的两起事件——员工钓鱼攻击和第三方白名单披露——都是出口数据通过允许的路径离开。在这两种情况下,模型层无法帮助;没有异常可捕捉。当所有概率性防御都失灵时,确定性边界才是最后的防线。
- 将隔离强度与用户的监督能力相匹配。 能读懂bash的开发者与不能读懂的知识工作者并不面对相同的威胁模型。用户能否评估智能体即将执行的操作,这个问题应该帮助确定隔离策略,而在任何方向上的错误回答——对专家来说摩擦太多,对非专家来说信任太多——本身就是一种失败。
- 警惕自定义组件。 经过实战检验的虚拟化管理程序、系统调用过滤器和容器运行时比你所构建的任何东西都承受过更多的敌对关注。在本文描述的每一次部署中,标准原语都保持稳定,而我们周围的自定义工作却暴露了缺陷。
最终,尽管智能体可能是一种新型软件,但它们与系统的交互并不是。它们仍然读取文件、打开套接字、生成进程;这使得使用成熟工具进行隔离成为一种至关重要的可行防御。随着AI的发展,部署的风险收益平衡将继续变化,但对爆炸半径设定硬限制通常会将这一平衡推向正确的方向。
致谢
作者:Max McGuinness, Mikaela Grace, Jiri De Jonghe, Jake Eaton, and Abel Ribbink。
我们还要感谢Hanah Ho, Hasnain Lakhani, Pedram Navid, Molly Villagra, Maya Nielan, Akila Srinivasan, Sam Attard, Alfred Xing, Mohamad El Hajj, Gabby Curtis, David Dworken, Adam Jones, Amie Rotherham, Christian Ryan, Lucas Smedley, Brett Andrews等人的贡献。
特别感谢我们的安全和产品工程团队,以及报告过Claude产品漏洞的个人和组织。
脚注
Claude Code自动模式将命令批准委托给基于模型的分类器;它最小化了摩擦(大约0.4%的正常命令被阻止),代价是遗漏了一小部分风险命令(约17%的过度活跃操作通过),因此它只是沙箱内多层防御中的一层,而不是替代品。