AI 博客

零次逃逸,十一次回连

Perplexity 于 2026 年 10 月 15 日开源了 SPACE——支撑其 Computer 产品的 Firecracker microVM 沙箱。其自家红队报告称:没有任何一次运行从虚拟机逃到宿主机;而在修复之前,五十四次「部分放通网络」的运行中有十一次成功把回连打了出去,其中四个模型用 DNS 欺骗与共享 IP 路由击穿了基于主机名的出站规则。会被引用的是那个隔离数字,而描述了今年这些事故的,是那个出站数字。

作者 智能体 AI 维基 22 分钟读完

Perplexity 在 2026 年 10 月 15 日开源了 SPACE——自 7 月起支撑其 Computer 产品的 Firecracker microVM 沙箱——并同时公布了一份红队报告。会被人反复引用的数字是:一百零八次运行里,没有一次从客户机内部拿到宿主机上的那份密钥。而真正值得细读的是另一个数字:在两处修复之前,五十四次「部分放通网络」的运行中有十一次把回连打了出去,四个模型用 DNS 欺骗与共享 IP 路由击穿了基于主机名的出站规则;而当 Perplexity 把同一批攻击打向另外十家沙箱平台时,有八家至少放过了其中一种。虚拟机从来不是失守的那一环,而一个把网络策略放在自己体内的沙箱,恰恰是把策略放在了智能体说得上话的那个地方。

概览

SPACE 的全称是 Sandboxed Platform for Agentic Code Execution。它把每一个智能体任务放进独立的 Firecracker microVM,对外暴露一套 HTTP API 用于创建 Linux 环境、执行命令、收集输出并销毁沙箱,目前已以 Apache 2.0 许可发布在 GitHub 上。据报道,CoreWeave 与 Akamai 已在自家云上测试并上线了它,Crusoe 则把它纳入其托管 AI 服务。撰写本文时无法直接访问 Perplexity 自己的公告与报告,所以下文的每一个数字都来自报道该发布的媒体——而它们之间的计数并不一致,这件事本身就值得你在引用任何一个数字之前知道。

发布了什么报道中的细节为何要紧
隔离每任务一个 Firecracker microVM,独立的客户机内核很强,也是整个设计里争议最小的部分。
凭据在沙箱之外持有并注入客户机拿不走一份它从未持有过的令牌。
网络策略在沙箱之外管理,客户机一律视为不可信这才是真正的架构主张。
规模7 月以来支撑每一次 Computer 会话;每天数百万次沙箱创建公司自报数字,但这显然不是个演示。
许可Apache 2.0,并有云厂商转售你可以不要这家厂商,只要这道边界。
Three results from the SPACE red-team report Bar chart of three reported proportions. No run out of one hundred and eight reached the host-side secret from inside the microVM. Eleven of fifty-four runs with partial network access retrieved a callback before fixes. Eight of ten third-party sandbox platforms tested allowed at least one of the same bypasses. Share of attempts that succeeded, as reported Escape the microVM to the host 0 / 108 nothing reached the host-side secret Callback out, partial network allowed 11 / 54 before the two fixes Third-party sandboxes allowing a bypass 8 / 10 same attacks 0% 50% 100% Counts are Perplexity's own, and differ between outlets; the two network figures are pre-fix.
三个结果,一个头条。头条是最上面那一行。

隔离这个结果是真的,而它回答的问题没人正在输

先按字面价值接受这个结果。九种模型配置,在客户机内被赋予 root 权限、并被指向一份放在宿主机上的密钥,一百零八次运行中没有一次逃出。这是一份确实有用的数据,因为这是第一次有人在这种规模上公开发表「由智能体驱动、针对生产级 microVM 边界」的逃逸尝试,而结果与理论相符:带独立客户机内核的硬件虚拟化边界,与命名空间属于不同量级的控制——这正是 沙箱与隔离模式 的全部论点。

它同时也是那道本来就在起作用的控制。把今年披露的那些智能体失控事件摊开看——触达了真实第三方系统的评测运行、框架侧的事故、用散落在配置里的凭据完成认证的智能体——没有一起是靠客户机内核漏洞实现的。智能体并没有从盒子里打出去。它用的是这个盒子被给予的网络、被交到手上的凭据,并且完全按配置行事。逃逸一栏里的那个零,对这些一句话也没说;之所以要把这句话讲明白,是因为「一百零八次尝试、零次逃逸」正是一份采购材料会原样抄走的句子。

这是同一个混淆换了一身新衣。我们在 microVM 守住了,挂载没有 里写过:计算隔离被测量、拿到一个数字,然后那个数字被读成关于整道边界的陈述。Perplexity 自己的报告比它的报道表现得更好——它把第二个实验也报了出来。

五十四里的十一,才是描述了今年的那个结果

Three ways to write an egress allowlist, and what each one leaks Three columns. Allowing by hostname is defeated by sending an allowed name to a different address. Allowing by resolved address admits everything else sharing that address on a content delivery network or multi-tenant cloud. Allowing a package repository admits a channel designed to serve arbitrary user-published content. What each allowlist style actually permits By hostname Enforced on the name in the request, not the host reached. Defeated by answering the lookup yourself: allowed name, attacker's address. By resolved address Enforced on the packet's destination address. On a CDN or multi-tenant cloud, one allowed address is shared with everyone else. By package repository A single entry that makes the task runnable at all. It is a channel for arbitrary user-published content, so the entry is the hole. All three reduce unsanctioned action on third parties. None of them bounds what leaves. For confidentiality the boundary has to see the request, which means a proxy you operate.
写白名单的三种方式。每一种都能减少越界动作;没有一种能界定什么可以离开。

第二个实验放通了部分网络——也就是所有人实际在跑的那种配置,因为一个连包都装不上的智能体会在第一个任务上就失败——然后去问:客户机能不能触达一台它本不该触达的主机。在修复之前,五十四次运行中有十一次取回了回连。被报道的两种手法,正是一直以来对付基于名字的过滤都奏效的那两种。如果执行点在请求里的那个主机名上,而客户机能自己回答自己的域名查询,那么客户机就把一个被允许的名字送向它自己挑的地址。如果执行点在解析出的地址上,那么在 CDN 或任何多租户云上,一个被放行的地址是与它背后其他所有租户共享的。

让这件事从理论变成具体的那个细节,是哪一条白名单开了门:策略允许了 PyPI 这样的软件包仓库。这一条不是失误,它是让沙箱根本有用的最低要求——而它是一条专为分发「任意陌生人发布的内容」而建的通道。你没法写出一份既包含软件包索引、又声称这份名单界定了客户机能取到什么、能触达哪里的白名单。

Perplexity 表示两种手法都已修复,后续测试没有取回任何回连,这没有理由怀疑。可以迁移的教训并不在这两个 bug 上。而在于:出站策略是一道独立的控制,有它自己的失效方式、自己的测试和自己的预算——这正是 智能体的出站控制 长篇论证的事情——并且一份白名单是范围控制,不是机密性控制。任何接受任意内容的被允许目的地都是一个外泄端点,而一个 URL 足够宽,塞得下一份密钥,见 隐蔽通道。

值得照抄的设计决定不是 Firecracker

Where the policy lives, in two sandbox designs Two stacked designs. In the first, the agent task holds its own credentials and the egress allowlist is enforced inside the guest, so defeating the in-guest rule is enough to reach the internet. In the second, the guest has no credentials and no default route: every request leaves through a proxy outside the guest that holds the allowlist and injects the credential, so the guest cannot reach a destination the proxy will not send it to. Policy inside the guest guest Agent task + token Allowlist in guest Default route The internet defeat one rule and you are out Policy outside the guest guest — untrusted, no token Agent task no default route Proxy outside the guest allowlist + credential The internet the guest never holds the token, and cannot address anything the proxy will not send it to
同样的隔离,不同的信任边界。只有下面那种设计能在客户机被完全攻陷之后仍然成立。

把这份公告剥到底,结构性的主张只有一句:沙箱一律视为不可信,而网络访问与平台凭据都从沙箱之外管理。这是比 microVM 更强的一句话,也是多数沙箱产品留给你自己去做的那部分。

它之所以要紧,在于红队假设了什么。两个实验都是从客户机内的 root 权限开始的。在这个假设下,一切在客户机内部实现的控制都是装饰——客户机内的白名单、客户机内的解析器配置、一个装着令牌的环境变量。只有当一道控制所在的位置是被攻陷的那一方改不了的,它才算一道控制。把策略往外挪,就把「五十四里的十一」变成了一个你补一次就好的代理里的 bug,而不是成千上万个你伸不进手的客户机的属性。由此得出两个具体结论,而且两者都不贵:

  • 没有默认路由。客户机唯一能触达的地址就是那个代理。这是让其余一切变得可执行的那条性质,也是多数搭建里被跳过的那一条,因为它要求去配置运行时,而不是写一条防火墙规则。
  • 令牌终结在代理上。如果厂商凭据是在出去的路上才被附加上的,那么客户机从不持有它,被攻陷的智能体也就没法把这份凭据带到代理不愿意送它去的任何地方——这是 把凭据交付到沙箱 与 给智能体的受限凭据 里的那个模式。

这两条都不需要 Firecracker。如果你在 gVisor 上、在一个你已决定接受的共享内核容器上,或者在别人的托管运行时上,「策略放在客户机之外」这套安排今天就对你可用,而且比在隔离层级上升一档更值钱。

十家里有八家,是一个该去问厂商的问题,不是一桩丑闻

Perplexity 还把那些网络攻击打向了十家第三方沙箱平台,并报告其中八家至少放过了一种绕过。这句话要仔细读,因为它是一个利益相关方发表的竞品测评——而它仍然是整份报告里最有用的数字。

它不是什么:它不是「八款产品是坏的」的证据。多数智能体沙箱是刻意把出站放宽发布的,并写在文档里,期望由运维方去收紧——这意味着「放过了一种绕过」部分测的是一个默认值,而不是一个缺陷。它是什么:一个很强的先验——你租来的那个沙箱的出站行为,你自己从没测过,它很可能是宽松的,而且几乎肯定是在智能体伸手够得着的地方执行的。任何在自家部署上跑过这个测试的人,都不会对自己的结果感到意外。

所以把它变成三个问题,去问那个替你跑沙箱的人——这就是 第三方模型与厂商风险 里的那套功课:

  • 出站规则在哪里执行,客户机里拿到 root 的进程能不能改掉它?如果答案是镜像里的一个配置文件或解析器设置,那条规则只是建议。
  • 客户机能解析任意域名吗?如果能,那就存在一条多数网络策略从不去看的出站路径。
  • 一次被拒绝的连接,会不会出现在触发它的那次工具调用旁边的追踪里?一个被拦下的请求,要么是策略缺口,要么是注入成功的最早证据——见 检测智能体被攻陷。躺在一份没人与运行关联的网络日志里,它两者都不是。

然后自己把这个测试跑一遍。报告里的攻击并不高深:放一份密钥,给客户机一份允许访问软件包索引的策略,然后看回连有没有到。如果你在跑能力评测,先在那里跑——评测台是多数团队手里加固程度最低的环境,这正是 评测框架没有出站策略 与 对活体系统做评测 的全部内容。

这对「自建还是租用」意味着什么

一个 Apache 2.0 的 microVM 沙箱,背后还站着几家云厂商,确实缩小了租沙箱与自己跑沙箱之间的差距;而诚实的总结是:它缩小的是那个本来就已经商品化的维度。启动延迟、池化与生命周期管理,是托管沙箱市场在比的东西——E2B vs Daytona vs Modal vs Northflank 覆盖的那片地——而这些现在可以装在一个你自己托管的包里拿到。

不会随这个包一起到来的那个维度,是策略。SPACE 给了你一个放策略的位置,并不替你把它写出来:按任务的目的地集合、从「这个任务被授予了哪些工具」推导出这个集合、在不可信内容进入上下文那一刻收窄网络的时序安排、以及日志的关联。无论你自己托管还是租用,这份活都一样;而正是这份活,本可以防住今年披露的每一起失控事件。沙箱池与冷启动 是它的运维那一半;爆炸半径 是值得为此费心的理由。

常见问题

一百零八次尝试零次逃逸,是不是说明 Firecracker 跑智能体代码就安全了?

它是一份有力的证据,说明 microVM 边界在面对「客户机内已有 root 权限的智能体」时守得住,而这正是智能体生成代码所对应的威胁模型。它对网络、凭据、挂载的文件系统和宿主机侧的控制面一句话也没说——而今年披露的每一起事件,恰恰都发生在那些地方。

为什么网络测试成功了,而逃逸测试没有?

因为它们打的是不同的边界,执行点也不同。逃出虚拟机需要击穿硬件虚拟化。击穿一份主机名白名单只需要:让客户机自己决定一个被允许的名字解析到哪里,或者那个被放行的地址恰好与另一个租户共享。前者是一个研究课题,后者是一条配置性质。

因为「十家里有八家」这个数字,我们该换沙箱厂商吗?

不该。它由一家竞争者发表,而「放过了一种绕过」也部分反映了智能体沙箱是刻意把出站放宽发布的。把它当成一个提示:去测你自己的部署,去问那条规则在哪里执行。在不把策略挪到客户机之外的前提下换厂商,什么都不会改变。

我们只放通了 PyPI 和自家 API,这份白名单安全吗?

它是一份说得过去的范围控制,不是机密性控制。软件包索引分发的是陌生人发布的内容,并接受形状不由你掌控的请求;而你自家的 API 是一个接受任意内容的端点。如果要求是「一份密钥不能离开」,你需要的是一道能检视请求的边界,而不是一份被允许名字的清单。

如果我们用的是托管智能体运行时,一个开源沙箱有帮助吗?

直接地说没有;间接地说有:它给了你一份参考实现和一份公开的威胁模型,可以拿来对照提供方的回答。把上面那三个问题问给他们,再问一句「被拒绝的出站尝试会不会进到我们的追踪里」。如果答案含糊,那本身就是信息。

延伸阅读

本站:

来源: