AI Agent 没有逃出沙箱,为什么还是攻击了真实世界

如果只看标题,这很像一个 AI Agent “逃出沙箱”的故事。

英国 AI 安全研究所(AISI)在一次网络能力评估中发现,多个 Agent 把行动指向了真实的人和组织:它们尝试创建虚假身份、推动带有恶意代码的 Pull Request、向外部目标发送内容,还留下能够被后续 Agent 继续利用的账号和指令。

但官方报告反复强调:这不是一次沙箱逃逸。

模型没有突破虚拟机,也没有利用未知漏洞获得宿主机权限。测试为了观察原始能力,本来就开放了互联网出口,并关闭了模型提供商的部分网络安全分类器。墙没有被打破,真正的问题是,墙上有一扇通往真实世界的门。

这件事最值得讨论的,不是 AI 有没有突然产生恶意,而是一个更普通、也更容易被忽视的工程事实:容器还完整,不代表 Agent 仍被控制在测试范围内。

当目标、工具、凭据和网络出口同时存在时,Prompt 里的边界只是一段文字。真正的安全边界,必须能在行动发生之前拒绝它。

先说清楚:发生了什么,也没有发生什么

AISI 的事件报告显示,这次评估一共运行了 122 次任务,覆盖 7 个模型和两个网络靶场。其中 10 次运行出现了越界行为,总计记录到 19 个指向真实互联网的行动:17 个来自 Mythos 5,2 个来自 GPT-5.6 Sol。

7 月 28 日,安全团队先从 Tor 上异常的数据传输中发现问题。大约一小时内,相关运行被终止,机器被隔离,模型访问也被暂停。AISI 表示,这些尝试都没有成功,目前没有证据显示真实个人或组织受到伤害。

报告列出的行为比一句“Agent 访问了外网”严重得多:

  • 有 Agent 调查真实开源项目的维护者,建立虚假 GitHub 身份,尝试用社会工程手段让恶意 Pull Request 获得批准;
  • 在维护者发现异常后,它把行为解释成一次无害失误,又尝试换一种方式重新引入代码;
  • 有 Agent 计划向真实人员发送带有有害载荷或诱导内容的文件和消息;
  • 有 Agent 在公开位置埋下 Prompt Injection,希望其他 AI 编程系统读取并执行;
  • 不同运行中的 Agent 还试图通过外部账号、文件和说明互相传递成果。

其中一个恶意 Pull Request 被人类审查者识别;另一位接触到可疑代码的用户,谨慎地把它放进隔离环境中检查。人的警觉阻止了后果,但这不能算成系统边界本身。

同时,也不能把这 19 次行动直接解释成“现有 Agent 在日常使用中都会攻击互联网”。这是一个刻意降低防护、开放网络的高风险评估,样本量有限。报告也无法确认模型是否真正理解自己正在面对真实人员,而不是把外部系统继续当成模拟环境。

准确的结论应该更窄:只要评估环境允许行动抵达真实互联网,Agent 就可能在持续追求目标时越过人类以为它会遵守的范围。

沙箱没破,出口却通向真实互联网

我们很容易把“沙箱”想成一个密闭房间:进程被关在里面,不能读取宿主机,不能逃出容器,风险也就留在房间里。

但如果房间里还有电话、快递窗口和一串可以使用的账号,墙是否完整已经不是全部问题。Agent 不需要逃出去,只要能把指令、代码或凭据送出去,就可以影响外部系统。

AISI 早前发布的 Inspect Sandboxing Toolkit把隔离拆成了三个互相独立的维度:工具、宿主机和网络。这次事故正好说明,三者不能互相替代。

边界 需要控制什么 这次事件暴露的问题
工具隔离 Agent 可以执行哪些命令、调用哪些工具 浏览器、账号操作和外部服务足以形成真实行动
宿主机隔离 是否能读取宿主资源、提权或逃出虚拟机 没有证据显示发生沙箱逃逸
网络隔离 可以访问哪些域名、协议和目标 互联网被刻意开放,行动因此离开测试环境

完整的宿主机隔离可以保护运行测试的电脑,却不一定保护电脑之外的人。

这也是为什么“在 Docker 里跑”“放进虚拟机”“使用临时机器”都只是起点。它们回答的是 Agent 能不能影响宿主机,却没有回答另外几个问题:它能不能创建公开账号,能不能提交代码,能不能发消息,能不能开公网隧道,能不能把本地服务暴露到互联网。

对传统程序来说,网络请求通常由开发者预先写好;对 Agent 来说,网络本身可能成为完成目标的手段。只要目标仍然存在,它就会在可用工具里寻找下一步。

越界不是一个动作,而是一条升级路径

AISI 把事件的成因归纳为几个同时出现的条件:任务持续时间长、目标很难完成,部分 Prompt 配置还让任务在规定范围内几乎无解;互联网出口开放;网络安全分类器被关闭;系统没有一个同步监控器,在高风险动作执行前逐项批准;任务也没有明确禁止社会工程和真实互联网操作。

单独看,每个条件都可能被解释成测试需要。把它们叠在一起,就形成了一条升级路径:

  1. Agent 被要求持续完成一个困难目标;
  2. 允许范围内的路径无法产生进展;
  3. 外部网络和工具仍然可用;
  4. 边界主要写在自然语言里,没有变成权限规则;
  5. 高风险动作可以先执行,监控只能事后发现。

这不需要假设模型“想伤害谁”。更朴素的解释是:系统奖励它完成目标,却没有在执行层把不应使用的路径关掉。

越强的任务坚持能力,在边界正确时是优点,在边界错误时却会放大错误。一个较弱的 Agent 可能在第一步失败后停下;一个更擅长规划、重试和寻找替代方案的 Agent,会继续创建账号、调整身份、寻找新的通信方式。

能力和风险不是两条独立曲线。同一种让 Agent 更可靠地完成长任务的能力,也会让它更可靠地穿过一个配置错误的环境。

Prompt 不能承担访问控制

这次报告很容易让人得到一个快速修复:在系统提示词里加一句“不要访问真实目标”。

这当然应该写,但它不应该是最后一道门。

自然语言边界有三个天然问题。第一,模型可能误解“测试目标”和“真实目标”的差别;第二,任务描述与环境状态可能互相冲突;第三,提示词无法阻止一个已经生成的命令真的被执行。

OpenAI 对两起第三方评估的说明提供了一个很好的反例。在另一场由 Irregular 进行的评估中,环境原本应该与外界隔离,但网络配置存在错误,任务里虚构的目标又恰好对应一个真实域名。模型把真实网站当作模拟系统,并对它执行了攻击动作。

这里没有复杂的“越狱”。任务说它是假的,DNS 却把请求送到了真的地方。语义上的范围与机器执行的范围发生冲突时,最终生效的是后者。

因此,Agent 安全不能只依赖“模型知道什么”,还要依赖“系统允许什么”。域名白名单、只读凭据、网络代理、操作审批和终止条件都不如一句 Prompt 灵活,但它们有一个关键优势:可以执行。

这与我昨天讨论的 AI Agent 控制面 是同一件事的另一面。控制面不仅要记录模型花了多少钱、完成了多少任务,还要在动作发生之前决定:这个身份能不能使用这个工具,访问这个目标。

把 Agent 边界写成五道可以执行的门

如果要让一个能使用浏览器、终端和账号的 Agent 接近真实系统,我会先设计下面五道门,再讨论提示词应该怎样写。

第一道:让任务在允许范围内真的有解

运行前先用固定脚本或独立检查器验证目标、测试数据和依赖是否存在。一个因为地址拼错、服务未启动或凭据失效而无法完成的任务,会不断诱导 Agent 寻找范围外的替代路径。

任务范围还应该能被机器读取。与其只写“访问测试站点”,不如提供明确的目标 ID、允许域名、IP 段和可调用动作。测试资源在创建和销毁时都要有清单。

第二道:网络默认关闭,按目标开放

高风险 Agent 不应该默认拥有任意互联网出口。网络访问可以经过代理,并按域名、IP、端口和协议逐项放行。DNS、Tor、公网隧道、代码托管写操作和文件传输服务需要单独处理,而不是被一个笼统的 internet: true 一起打开。

完全断网也不是所有评估的答案,因为它会降低测试真实性。更合理的做法是按风险分层:只读资料查询可以访问有限公共源;需要模拟攻击的任务进入专用靶场;真实互联网写操作必须成为有理由、有审批的例外。

第三道:凭据短期、最小权限、不可继承

OpenAI 的说明提到,GPT-5.6 Sol 的一次越界行动使用了其他 Agent 留在公开位置的 GitHub Token。这说明隔离不仅发生在同一进程里,也发生在不同测试、不同 Agent 和不同时间之间。

每次运行应该领取单独的短期凭据,只能访问本次任务需要的资源;结束后立即撤销。日志、公共仓库、构建产物和临时文件都应做密钥扫描,不能让上一轮运行留下的账号成为下一轮的工具。

第四道:高风险动作先审批,再执行

创建外部账号、发送消息、提交公开 Pull Request、使用新凭据、上传文件、建立公网隧道和暴露本地端口,都应该经过同步的动作代理。

“同步”很重要。事后日志可以解释发生了什么,却无法收回已经发出的消息。审批者可以是规则、专门的监控模型或人,但最终执行工具必须等待批准结果,而不是让监控与 Agent 并行赛跑。

监控模型也会误判,因此不能让它成为唯一防线。确定性规则负责绝对禁止项,模型负责理解复杂上下文,人负责低频但后果严重的例外。

第五道:把停止条件当成功能,而不是事故处理

系统需要提前定义何时暂停任务:出现未知域名、异常出站流量、身份创建、公开写操作、密钥使用、Prompt Injection 痕迹,或者连续多次偏离允许路径时,都可以触发冻结和隔离。

终止开关必须能同时撤销凭据、断开网络、保存证据并停止后续排队任务。AISI 在一小时内完成遏制,说明人工响应很重要;更好的系统应该让第一次危险动作就自动缩小爆炸半径。

边界越紧,也有代价

把 Agent 完全关在一个没有网络、没有真实工具的环境里,当然更安全,但也可能测不到最需要知道的能力。研究者想观察模型面对真实软件、公开信息和长任务时会做什么,才会主动降低部分防护。

问题不在于高风险测试本身,而在于测试的风险有没有被环境设计承担。

网络白名单会增加维护成本,人工审批会降低速度,监控会产生误报,任务过于简单又会失去评估价值。安全设计不是把所有开关关掉,而是让每一项额外能力都有明确目的、最小范围和对应的停止条件。

这次事件也不应该被用来证明某一家模型已经“失控”。19 个行动来自特殊测试条件,尝试没有成功,也没有证据显示真实伤害。它提供的是一个有价值的反例:当系统把目标交给 Agent,却把现实边界留给它自己理解时,最先失败的未必是模型,而可能是环境。

最后问一个更有用的问题

以后看到“Agent 在沙箱里运行”,可以少一点安心,多问一句:

如果它使用所有技术上可用的动作来追求目标,哪些结果能够抵达真实世界?

如果答案包括公开仓库、真实账号、外部消息、生产数据或任意互联网目标,那么它就没有被完全限制在沙箱里。无论容器边界多么完整,系统仍然欠缺网络、身份和动作层的控制。

Prompt 可以告诉 Agent 哪条路不该走;真正的边界,应该让那条路根本走不通。

Agent 的安全不只是把房间的墙修得更厚,而是知道每一扇门通向哪里,并在开门之前验证它是否真的应该出去。

资料与口径