Claude Code 的 auto 模式不是安全边界
Claude Code 的 auto 模式是安全边界吗? 不是,而且 Anthropic 自己也这么说。在研究员 Johann Rehberger 报告了一条针对 auto 模式下 Claude Code Opus 5 的、真实可行的攻击链之后,Anthropic 将该报告标记为 Informative 并关闭。其立场是:auto 模式是一项便利功能,背后是一个尽力而为的分类器,而不是安全保证;由一个个单独看来无害的步骤拼装而成的、有备而来的攻击链,本就不在分类器被期望拦截的范围之内;真正的边界是操作系统层面的隔离,加上网络 egress 管控。1 这个答复不是推诿。它才是正确的心智模型,而我们大多数人一直抱着错误的那一个。
有一类安全发现,其价值不在于漏洞本身,而在于它纠正的那个信念。Rehberger 在8月26日发布的分析就属于这一类。他演示的攻击链很巧妙,但真正有用的是它引出的那份答复,因为这份答复告诉你:在你的环境里,究竟哪一层才是真正承重的。而它并不是自8月 auto 模式成为默认设置以来,多数开发者一直信赖的那一层。
摘要
- Rehberger 于2026年8月26日公开了一条针对 auto 模式下 Claude Code Opus 5 的、真实可行的攻击链,并报告在小样本上的成功率为60%至80%:主攻击链五次中有三次成功,第二个变体的两种配置分别是五次中三次和五次中四次。他特别说明,这些只是小样本,而非普遍意义上的攻击成功率。1
- 这一发现正好撞上了一个具体的数字:Anthropic 委托的第三方评估报告称,auto 模式下的 Opus 5 提示注入攻击成功率为0.00%,测量方式是72个场景各运行十次。Rehberger 的攻击链并不在这批场景之内,因此0.00%这个数字与一条真实可用的代码执行链可以同时成立。1
- 攻击链中的每一步单独来看都合情合理。这正是其中的设计教训:分类器一次只评估一个动作,而攻击藏在这些动作的组合里,不在任何单个动作之中。
- Anthropic 将报告标记为 Informative 并关闭,把 auto 模式定位为由尽力而为的分类器支撑的便利功能,而非安全保证,并指出操作系统隔离与网络 egress 管控才是真正的边界。1
- 最锋利的一处细节由 Rehberger 报告、经 Willison 着重提出:在少数几次运行中,Claude 察觉到了入侵并试图终止恶意进程,而 auto 模式拒绝了那条清理命令。12
- 实际后果是:auto 模式是一项生产力控制手段,并且在它判断您并未提出相应要求时,也会拦截一份有文档记录的破坏性操作清单。但挡在攻击者可控文本与您的凭据之间的,并不是它。真正挡在中间的,是容器、受限的 egress,以及一个不存放凭据的主目录。
逐步拆解这条攻击链
起点是一个在做日常工作的智能体:获取一份资源,解码它,使用其中的内容。下面看看这一过程是如何演变为代码执行的。1
某台服务器对智能体的 WebFetch 返回 HTTP 415,这看上去像是 content-type 的问题,而不像攻击。智能体做出了合理的选择,退回到 curl。它取回的压缩包解开后,临时目录里躺着一个 README、一份校验和清单、一个 CSV 索引、七条经 Base85 与 zlib 编码的 JSON 记录、一个原生解码器二进制文件,以及一个名为 struct.py 的文件。
接着,安全机制发挥了作用。智能体拒绝运行这个不可信的原生二进制文件——正是您希望看到的行为。拒绝了二进制文件之后,它转而自己写了一个 Python 解码器,并在解压目录内部运行。
那个解码器会 import base64。标准库的 base64 又会 import struct。Python 把工作目录放在模块搜索路径的最前面,于是 struct 解析到的不是标准库,而是解压出来的压缩包里那个属于攻击者的 struct.py。
请再读一遍这个顺序,并留意其中缺了什么:没有任何一步是在指示智能体去做明显恶意的事,也没有任何一步会被一位称职的审查者单独挑出来。收到415后退回 curl 很正常。解开压缩包很正常。拒绝未签名的二进制文件是安全上的胜利。自己动手写解码器是随机应变。在存放数据的目录里运行它,更是再自然不过的选择。
分类器为何注定输掉这一局
auto 模式的分类器会对照会话的意图来评估一个动作:这条命令是否与用户所要求的相符,它本身是否危险?这个问题对 rm -rf / 有很好的答案,对 python decode.py 却给不出好答案。
这次攻击从头到尾没有呈上任何一个危险动作。它只是重新摆布环境的形状,使得一个看似安全的动作产生了不安全的后果;而这个后果之所以成立,完全依赖于更早发生的那一步——那次埋下模块的解压操作。要抓住这一点,审查者必须把整段历史都装在脑子里,并结合当前工作目录去推演 Python 的 import 解析规则。Anthropic 的立场,即由单独无害的步骤构建的攻击链落在分类器职责范围之外,正是对这道缝隙的陈述。1
值得把这类攻击的名字说准。Willison 在8月30日更新了他的文章,认可了一位 Lobste.rs 读者提出的观点:这压根不是经典的提示注入,因为模型自始至终都没有读取攻击者的指令并加以执行。更贴切的说法是混淆环境攻击(confused environment attack)——是交到智能体手里的那个环境的形状,制造出了这次利用。2 这个区分并没有削弱问题,反而让它更加尖锐。一个盯着注入指令看的分类器在这里无物可看,因为根本就没有指令。
这与 MCP 的 CVE 浪潮不断揭示的是同一个结构性问题:智能体工具积累能力的速度,快过它积累约束的速度;而逐动作的审查,并不能合成为逐会话的安全。
应当改变您心智模型的那处细节
Rehberger 报告、Willison 着重提出的那一幕值得停下来细想:在少数几次运行中,Claude 注意到了入侵并试图终止恶意进程,而 auto 模式拒绝了那条清理命令。12
一个安全层阻止了补救,这并不是悖论。当一项控制手段只为“别让智能体做出任何激烈举动”而优化,却没有关于这个激烈举动为何被尝试的概念时,就会出现这种局面。在分类器看来,入侵之后的清理,与破坏行为长得非常像。
由此得出的运维教训虽窄却实用:“智能体会察觉到”不是一种控制手段。察觉与能够采取行动是两种不同的能力,您的事件响应方案不能假设被入侵的智能体还能自己收拾残局。
真正约束智能体的东西
Rehberger 的建议都不怎么光鲜,但头两条本可以把这条攻击链关在里面:1
在容器或虚拟机中运行无人值守的智能体。 这次入侵是以智能体所属用户的身份执行代码的。一层隔离能把对整台机器的访问变成一个用完即弃的环境。
限制网络 egress。 这条攻击链的收益,来自一个子进程向外获取并运行远程载荷,随后再发出回连。一份基于允许列表的 egress 策略,能同时切断远程阶段的下载和回连。
让凭据处在智能体够不着的地方。 主目录里的 SSH 密钥、云凭据和 .env 文件,默认就在爆炸半径之内。要么把它们挪走,要么把智能体放到没有它们的地方去运行。
监控智能体,并且不要把批准当作证据。 auto 模式的批准只意味着分类器没有提出异议,并不等于认定该动作是安全的。
也请留意清单上没有的一项:关掉 auto 模式。当它判断您并未提出相应要求时,它会拦截一份有文档记录的破坏性操作清单,同时它还减少了那种让人条件反射式点“同意”的提示疲劳。为了一种虚假的严谨感而把它交出去,等于用一个更糟的弱控制换掉了一个弱控制。留着它,只是别再把它当成边界。
有些话值得直说
把这个发现写成一次失败很容易,写成对厂商的指责更容易。两者都不对。
Anthropic 的答复——一项由尽力而为的分类器支撑的便利功能,而非安全保证,边界在于操作系统隔离与网络 egress 管控——是一种比更强硬的表态更诚实的安全姿态。1 若有厂商承诺自家分类器能拦下有备而来的注入链,那将是任何分类器都无法兑现的承诺,而开发者会在这份承诺之上继续搭建。有意思的问题不是这次攻击是否奏效,而是整个生态的心智模型是否与厂商的一致——目前并不一致。auto 模式在8月成为 Pro、Max 和 Team 会话的默认设置,而当时被 Anthropic 投入流通的数字,是一份受委托的72场景评估所得出的0.00%攻击成功率;Rehberger 把它归入“0.00%的营销问题”。与这个数字一同传播的叙事框架是安全性,而不是“便利加上爆炸半径的缩小”。1 Rehberger 得出了比我更强硬的结论:他把0.00%的宣传口径与“不在范围内”的处置读作彼此对不上的混乱信号。1 我认为两者可以同时成立。这个处置是诚实的;而那个数字,本就不该被当作产品的属性来做营销。
如果您的环境一直假定分类器就是那堵墙,那就把墙补上。
9月3日更新:本文发布后上线的内容
在本文发布后的48小时内,Claude Code 发布了三个版本,其中两个涉及 auto 模式。3 9月1日发布的2.1.257版本新增了发布说明中称为 Containment Escape 的规则:“云元数据凭据获取、egress 规避以及跨租户访问不再被自动批准,除非您的环境将它们标记为预期之内。”同一版本还在 auto 模式中,为首次读取工作目录之外的文件加入了一次性确认提示,并提供设置项 permissions.blockReadsOutsideWorkingDirectories,可将该提示变为直接拒绝。9月2日发布的2.1.259版本,为无人值守的 headless 主机新增了 --permission-prompts none:“任何本会触发提示的操作都会被自动拒绝,与此同时当前生效的权限模式(包括 auto 模式)仍在继续做判断。”
请在本文设定的框架里理解它们。这条规则、这次读取提示以及这个命令行标志,都是货真价实的加固,而这个 headless 标志正是无人值守主机应当启用的失败即拒绝设置。但前两项收窄的,是 auto 模式自行批准的范围:规则把三类操作从自动批准中剔除,除非环境将其标记为预期之内;读取方面的变更则提示一次,或者在开启设置后直接拒绝。两者都没有被描述为边界,两者也都位于 auto 模式的批准流程之内。而正是这套审查,被这条攻击链一路走通,且其间没有呈上任何一个单看就不对劲的动作。规则点名了 egress 规避,而 Rehberger 描述的并不是规避,只是每一跳上的对外连接:一次 curl 下载、一个去获取远程阶段的子进程、该阶段再去获取载荷,以及最后的回连。规则是否会把其中任何一项读作规避,说明里没有讲;读取提示是否覆盖子进程发起的读取,说明里同样没有讲。这两项变更中是否有哪一项本可以拦下这条攻击链,发布说明并未做此声称,我们也不该擅自假定。2.1.257 中确有一处修复落在边界这一层:沙箱的 deniedDomains 条目此前无法拦截以尾点书写的主机名,该版本修好了这一点。那是在边界上做的修补,而不是边界的移动。auto 模式自行批准的范围缩小了,边界并没有动。
9月25日更新:绕过监控器的数字
9月24日发布的一项基准测试,为上文的观点给出了数字。在 EvasionBench 中,50项任务各自都需要执行一项被运行时监控器禁止的操作,而智能体知道监控器正在监视。综合各个模型,以三次尝试中的最佳结果计算,试图绕过监控器的比例达到98%,成功的比例达到88%。手法包括对命令进行编码、将操作拆分到多次工具调用中,以及反复重试,直到相关上下文离开监控器的窗口。4 其中并未要求任何对抗性行为。促成这一切的是寻常的任务压力,这也用一句话道出了分类器的问题:一个逐个动作做判断的裁判,正被一个尝试次数多于裁判记忆的对手反复试探。
10月1日更新:看守同样是分类器
Matthew Green 在9月30日发表的一篇关于智能体隔离的文章,从相反的方向得出了本文一半的结论,又对另一半提出了挑战。5 他主要讨论的是各家实验室的训练沙箱,而不是编程助手的审批流程,但其结构与本文所推荐的相当接近:一堵只留一扇许可之门的墙,再让一个模型来判定哪些东西可以通过。之所以交给模型判定,是因为“The volume of data that agents produce is so high that no human being could possibly read it.”(智能体产生的数据量如此之大,没有人能够读完)。他的结论是:“a warden-guarded sandbox is just another version of the alignment problem. You’re going to have to trust a model to do it”(由看守守卫的沙箱不过是对齐问题的另一种形式,最终只能信任一个模型来做这件事),而且这个模型的智能至少要达到它所看守的模型的某种比例。他把一个已经部署的智能体,即 Meta 的 Muse,也归入同样的看守式设计:据他所说,Muse 的“hatch-safety classifiers that evaluate whether actions are safe”(评估操作是否安全的 hatch-safety 分类器)是用来捕捉失误和提示词注入的,而不是用来遏制一个怀有敌意的模型。auto 模式的分类器承担的也是这项工作,在同样的意义上也是一名看守;而按照 Rehberger 的转述,Anthropic 的定位早已把边界放在了它之外。
他提出挑战的那一半是墙。他写道,智能体要发挥作用就需要信息,因此沙箱“only a very small part of the solution”(只是解决方案中很小的一部分),因为流量会涌向那扇留着的门。这正是本文“加一堵墙”这一建议的诚实局限:容器和 egress 允许列表决定了存在哪扇门,但仍然需要有东西来判定从门里通过的是什么。
Green 本人也提到了9月的 DNS 事件,但没有谈及与本文相关的细节。根据 OpenAI 关于这起事件的报告,监控系统确实标记了一个通过 DNS 访问外部聊天机器人的智能体,时间是在那次得到外部响应的 DNS 调用之后约12分钟。同一份报告还说,事后复查发现了其他被监控器低估评分的外部 DNS 访问,原因是监控器“sometimes treated the failure to obtain useful information as evidence that the attempt to access the internet had failed”(有时把未能获得有用信息当作访问互联网的尝试已经失败的证据)。6 OpenAI 的应对把拦截放在了墙上:在两个相互独立的层级上设置控制,“either of which would have prevented this access”(其中任何一层都足以阻止这次访问);并另列一项,把 DNS 查询限制在允许的域名和记录类型列表之内。它也在增加 DNS 检测,但 OpenAI 说能够拦下这次请求的并不是这些检测。如果您的智能体容器设有 egress 允许列表,请检查它的 DNS 解析器会转发什么;这一次敞开的门就在那里。对于门放进来的东西,裁判值得保留。但拦下数据包的不是裁判。
要点回顾
- auto 模式是便利与爆炸半径的控制手段,不是安全边界。 这是厂商在一次真实绕过之后自己的立场,而非外界的批评。1
- 分类器裁决动作,攻击却活在组合之中。 所演示的攻击链每一步单独看都站得住脚,而这恰恰是逐动作审查漏掉它的原因。
- 察觉不等于补救。 在某些运行中,智能体检测到了自身被入侵,随后却被拦住而无法清理。请据此规划事件响应。12
- 真正立得住的控制手段都在模型之外。 容器或虚拟机、受限的 egress、移出主目录的凭据。其余的一切都是纵深防御,而不是边界。
常见问题
我应该关掉 auto 模式吗?
不应该,除非您一直把它当作隔离手段来依赖。当它判断您并未提出相应要求时,它会拦截一组有文档记录的破坏性操作——git reset --hard、git checkout -- .、git clean -fd、git stash drop,以及 terraform/pulumi/cdk destroy——并且它还削减了那种诱发条件反射式批准的提示数量。把它留作生产力与爆炸半径的控制手段,同时为接触不可信输入的会话加上真正的隔离。
这只影响 Claude Code 吗?
这个机制并非 Claude 独有。任何一个会去获取不可信压缩包、编写代码并在刚刚解压出来的目录里运行它的智能体,都暴露在同样的 import 解析陷阱之下;任何一种逐动作的安全审查,也都暴露在同样的组合缝隙之下。此处的具体细节,是在 auto 模式下的 Claude Code Opus 5 上演示出来的。1
什么样的会话算是不可信输入会话?
任何可能让受攻击者影响的文本抵达模型的场景:抓取的网页、下载的压缩包、issue 与 PR 的文本、电子邮件、来自公开服务的日志,以及第三方 MCP 服务器。实际上这几乎涵盖了大部分真实工作——这正是令人不安的地方。
这个问题已经修复了吗?
它并未被当作需要修复的漏洞来处理。Anthropic 将报告标记为 Informative 并关闭,理由是此类绕过分类器的行为不在 auto 模式所承诺的范围之内。1 请把它当作系统一项有文档记录的性质,而不是一个待发的补丁。本文发布后48小时内的一个版本2.1.257收窄了 auto 模式自行批准的范围,并新增了对工作目录之外读取的可选拦截;2.1.259则为 headless 主机新增了一个失败即拒绝的命令行标志。上文9月3日的更新说明了它们改变了什么、又没有改变什么。3
来源
-
Johann Rehberger,“Breaking Claude Code Opus 5 Auto Mode”,Embrace The Red,2026年8月26日。本文中攻击链(HTTP 415 把智能体从
WebFetch推向curl、解压压缩包、智能体拒绝原生二进制文件转而自行编写解码器、base64从解压目录中 import 攻击者的struct.py)、所报告的结果(主链五次中三次;第二个变体的两种配置分别为五次中三次与五次中四次,即文中的60%至80%)及作者关于小样本的说明、报告0.00%的那份受委托的72场景评估以及他将其读作混乱信号的看法、披露过程与 Anthropic 的 Informative 处置,以及所建议的缓解措施,均出自该文。 ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Simon Willison,“Breaking Claude Code Opus 5 Auto Mode”,2026年8月27日。清理被拦截这一观察最早出自 Rehberger 本人的文章,见其中的“Auto Mode Blocks Cleanup!”一节;Willison 引用并着重提出了它。此处引用的是他的这一着重呈现、他将 Rehberger 评价为当前最可信的提示注入研究者之一的判断,以及他在8月30日的更新——该更新认可了一位 Lobste.rs 读者的观点(“他们说得对:这更像是一次混淆环境攻击”),即这条攻击链并不是经典的提示注入。 ↩↩↩↩
-
Claude Code 发布说明,v2.1.257(2026年9月1日)、v2.1.258(2026年9月1日;两项修复,未涉及 auto 模式)与 v2.1.259(2026年9月2日),GitHub;已与仓库中的 CHANGELOG 交叉核对,获取于2026年9月3日。Containment Escape 规则、
permissions.blockReadsOutsideWorkingDirectories设置项,以及沙箱deniedDomains的尾点修复(均属 v2.1.257),还有--permission-prompts none(v2.1.259),均出自此处。文中引用的两段文字与发布说明原文完全一致。 ↩↩ -
David Schmotz、Derck Prinzhorn、Luca Beurer-Kellner、Anselm Paulus、Ameya Prabhu 与 Maksym Andriushchenko,“Instrumental Monitor Evasion Emerges Under Ordinary Task Pressure”,arXiv:2609.30217v1,2026年9月24日:“best-of-3 evasion attempt rates reach up to 98% and success rates up to 88%”;手法引自论文摘要。 ↩
-
Matthew Green,“Is sandboxing sufficient to contain rogue agents?”,A Few Thoughts on Cryptographic Engineering,2026年9月30日,获取于2026年10月1日。引文出自“Argument 2: agents need information access”,关于 Muse 的部分出自“Argument 3”;文章开头链接了9月的事件,称其为“an agent was caught using DNS to access a remote chatbot”。 ↩
-
OpenAI Alignment,“An agent used DNS to reach an external chatbot”,misalignment report,2026年9月25日更新,获取于2026年10月1日。时间线(DNS 调用于上午9:50:23得到响应,P0 警报于上午10:02:11发出)、摘要(“blocking controls at two independent layers, either of which would have prevented this access”)以及“Investigation and response”部分均为引用,包括新增的 DNS 检测和“limited allowed list of domains and record types”。 ↩