AI 博客

微 VM 守住了,挂载没有——Docker Sandboxes 的两次逃逸

Docker 9 月 15 日的公告描述了两条逃出 Docker Sandboxes 微 VM 的路径,而它们都没有碰到硬件边界。两者都是沙箱有意开出的通道里的符号链接竞态——virtio-fs 工作区共享,与客户机到宿主机的套接字转发——那里一直就是智能体沙箱真正的攻击面;而握着刀的那个「客户机」,是你自己的编码智能体。

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

硬件边界一处都没被攻破。Docker 9 月 15 日的公告描述了两条逃出 Docker Sandboxes 微 VM 的路径,而它们走的都是沙箱自己有意开出来的通道——工作区文件共享,以及从客户机通往宿主机的套接字转发。对任何为编码智能体采购隔离的人来说,这才是那条经得起时间的教训:你的爆炸半径不由隔离技术决定,而由服务于那些你亲手凿穿的孔洞的宿主机侧代码决定。

速览

两份公告、一个产品、一种根因。

编号严重程度受影响版本所在位置
CVE-2026-77179严重——CVSS v4.0 9.40.28.0 ≤ v < 0.42.0,macOSvirtio-fs 宿主机服务端(工作区共享)
CVE-2026-79994高危0.37.0 ≤ v < 0.42.0客户机到宿主机的 Unix 域套接字转发

两者都是符号链接替换竞态;其中严重的那个归类为 CWE-59,即访问文件前的链接解析不当。两者都在 9 月 7 日发布的 Docker Sandboxes 0.42.0 中修复,公告则在 9 月 15 日跟进。Docker 表示尚未发现被利用的情况。

Where the two Docker Sandboxes escapes crossed the boundary A coding agent runs as root inside a microVM with its own kernel and Docker daemon. A hardware virtualisation boundary separates it from the host, and neither vulnerability crossed that boundary directly. Two channels pass through it by design: the virtio-fs workspace share and the guest-to-host Unix domain socket relay. Both are serviced by a virtual machine monitor process running as the ordinary desktop user, and both were the location of a symlink race. Behind that process sit the rest of the home directory, credentials and other repositories. GUEST HOST (macOS) Coding agent, running as root permission prompts disabled, unattended Guest kernel its own Docker daemon its own Workspace, mounted read-write guest controls every path inside it Treat as hostile on some fraction of runs: one injected instruction is enough BOUNDARY hardware virtualisation — not crossed by either CVE virtio-fs workspace share CVE-2026-77179 Unix socket relay CVE-2026-79994 Virtual machine monitor process parses guest-controlled paths; runs as your desktop user Everything that user can read or write SSH keys · cloud credentials · browser profiles every other repository on the machine this is the part you get to make smaller
漏洞不在那堵墙上,而在穿墙而过的那两道门上。

到底坏在哪里

Docker Sandboxes 自 2026 年 1 月 30 日正式可用,它给每个编码智能体一个用完即弃的微 VM:自己的内核、自己的文件系统、自己的 Docker 守护进程、自己的网络栈,通过一个 sbx 命令行工具驱动。你的项目目录以可读写方式共享进去——因为一个改不了你仓库的智能体,算不上编码智能体。它的卖点是:你可以让 Claude Code 或 Codex 无人值守地跑(关掉授权提示),而一个被攻陷或失控的智能体仍然够不着宿主机。

第一个漏洞出在 virtio-fs 宿主机服务端,也就是提供那份共享工作区的组件。当它按先前保存的路径重新打开一个已被 unlink 的文件时,它会跟随符号链接。控制了工作区的客户机,可以在路径被记录之后,把某个父目录替换成一个符号链接,于是后续那次操作解析到了完全另外一个地方。结果是对虚拟机监视器进程所能触及的宿主机文件的任意读写——而在开发者的笔记本上,这个进程就是以开发者本人的身份在跑。

第二个漏洞是同一种形状,只是换了条通道。套接字转发先校验请求的套接字路径位于获批的工作区内,随后却用原始的路径字符串去建立连接,而不是用那个已被校验的句柄。在「校验」与「使用」之间把某个中间目录换成符号链接,宿主机就会去连接一个由客户机挑选的、位于工作区之外的 AF_UNIX 套接字。

两者都是针对符号链接的「检查时到使用时」竞态:Unix 世界里最古老的漏洞类别,之所以出现在一款 AI 产品里,是因为这款产品的全部工作就是在一个不可信方与你之间中介一个文件系统。也请注意这里没有什么。这不是一个授权漏洞——没有谁越过了自己被授予的权限。权限模型本身没问题;是实现它的代码把同一条路径解析了两次,得到了两个不同的答案。

那个不可信方,就是你自己的智能体

「一个控制了客户机的攻击者」这句话,出现在寻常的容器公告里,读起来像是指某个已经打进来的人。在智能体沙箱里,它读起来完全不同,因为客户机是你自己启动、然后又亲手指向互联网的那个软件。

编码智能体会读 issue 文本、依赖的 README、CI 日志、网页,以及它跑过的每条命令的输出。这些东西里任何一样都可能夹带指令,而智能体手里有一个 shell。这款产品自己的价值主张——关掉授权提示的无人值守执行——恰恰就是那种配置:当一次提示注入把「客户机」变成「控制了客户机的攻击者」的那一刻,没有任何人在看。要让这两个 CVE 变得要紧,你不需要一台被攻陷的笔记本,也不需要一个心怀恶意的内部人员。你只需要某个传递依赖里一份被投毒的 README,以及一个正在做它被买来做的事的智能体。

所以,给智能体沙箱评定严重程度时,起点不该是「客户机有多大可能是敌对的」。就假定它在一定比例的运行里是敌对的——因为这本来就是你买这个沙箱要处理的威胁模型。剩下的问题只有一个:当那条你不得不给出去的通道失效时,一个敌对的客户机够得着什么。

为什么两个漏洞出在同一个地方

Exposure of each channel a coding-agent sandbox opens through its boundary A four-by-four matrix. Rows are the workspace file share, the host socket relay, network egress, and credential passthrough. Columns are whether the channel can be removed, how much of its input the guest controls, whether host-side code parses that input, and what a failure reaches. The workspace share is high exposure on all four: it can never be removed, the guest controls it fully, host code parses it, and failure reaches the host filesystem. The socket relay is optional but otherwise high. Network egress is restrictable and medium. Credential passthrough is avoidable and guest-opaque, but a failure reaches accounts directly. Exposure of each channel, by how much guest-controlled input reaches host code Can you remove it? Guest controls input Host-side parser Failure reaches Workspace file share Never Fully Yes Host filesystem Host socket relay Optional Fully Yes Local services Network egress Restrictable Fully Partly Exfiltration Credential passthrough Avoidable No No Accounts Low exposure Medium High — where both CVEs landed
按「有多少客户机可控的输入抵达宿主机代码」给通道排序。这个排序能预测 CVE 会落在哪。

隔离技术本身的战绩不错。微 VM 给你一个独立内核和一道硬件强制的边界,而这两个 CVE 都没能撼动它——这也正是本站对 gVisor、Firecracker、Kata 与 Wasm 的比较从相反方向得出的结论。战绩弱得多的,是为了让墙里那个东西有用而横跨这道边界加装的那套半虚拟化管线:共享文件系统、套接字转发、剪贴板桥接、端口代理、凭据助手。那些代码跑在宿主机侧,解析由客户机控制的输入,而沙箱逃逸在过去十年里一直就住在那儿。

对智能体沙箱来说,这是结构性的,而非偶然。共享就是产品本身。没人会买一个看不见仓库的微 VM,于是那条属性最糟的通道——客户机可控的路径、宿主机侧的解析、另一头就是宿主机文件系统——同时也是你永远无法配置掉的那一条。对一次经由它发生的逃逸,正确的读法不是「厂商大意了」,而是:这个面还会再产出一个同类漏洞,而你的设计现在就该假定下一个已经在路上。

这也重新框定了选型时该问的问题。「它是真 VM 还是只是个容器?」是每个人都会问的那一个,而它只决定了那堵墙。真正决定你损失多少的问题是:挂进去了什么、监视器进程以谁的身份运行、以及你打补丁有多快。

周一该改什么

边界它承诺什么失效时客户机得到什么你能控制什么
微 VM/内核客户机代码无法在宿主机上执行一切——但这次它没有失效厂商选型、补丁版本
工作区共享客户机只看得见项目目录监视器进程能读写的每一个文件你挂了什么,以及以谁的身份运行
套接字转发客户机只够得着获批的套接字任何信任其套接字对端的本地服务要不要开启它
网络出站客户机只够得着允许的主机把它已经读到的东西外传白名单,以及是否存在白名单

从这张表出发,有四个具体动作,按回报从高到低排列:

  • 升级到 0.42.0 或更高。两个修复都在 9 月 7 日发布,比公告早八天。如果你是用包管理器而非桌面版更新程序安装的,请去核对已安装的版本,别想当然。
  • 把门后面的东西变小。工作区共享不必是你真实主目录里的某个子目录。给智能体一份专用检出,放在一条别的什么都不存的路径下——没有你的 SSH 密钥,没有你的云凭据,没有你其他客户的仓库。第一个 CVE 的触及范围是「VMM 用户可访问的宿主机文件」,而那到底有多大,由你来定。
  • 能不用日常用户身份跑沙箱就不要。在共享构建主机上这很直接,却很少有人做;在笔记本上它是摩擦,而诚实的取舍是主动接受这份风险,而不是默认承受它。沙箱与隔离模式讲了如何分层。
  • 按「设备类软件」的时钟打这类补丁,而不是按「开发工具」的时钟。一个开发工具的 CVE 听上去优先级不高——直到你注意到,它是一条从互联网来的内容通往你主目录的、无需认证的路径。把智能体沙箱当成面向互联网的软件来对待,因为在功能上它就是。

今天只做一件事的话,就做挂载那件。升级修掉的是这两个漏洞;改掉共享指向何处,修掉的是这一类。一个在一份用完即弃的检出里工作、旁边没有任何凭据的智能体,会把下一次同类逃逸从一起事件变成一个糟糕的下午——而且与打补丁的速度不同,维持这一点不花你任何代价。

常见问题

微 VM 的隔离本身被攻破了吗?

没有。两个 CVE 都不涉及逃出虚拟机的硬件边界或客户机内核。两者都是通过赢下一场针对符号链接的竞态,去滥用那些有意跨越该边界的宿主机侧服务——virtio-fs 文件共享与套接字转发。

我不用 macOS,会受影响吗?

CVE-2026-77179 的范围限定在 macOS。套接字转发那个漏洞 CVE-2026-79994 列出的受影响范围是 0.37.0 直到 0.42.0 之前,并未附带这项平台限定。无论什么平台都请升级,并按公告核对适用于你这套安装的范围。

这是不是说明用容器也一样好?

不是,而且这个推论的方向反了。微 VM 的边界守住了;容器共享内核的边界更弱,而且它照样会坐在同一份共享工作区的背后。这份公告说明的是,穿过边界的那些通道值得与边界本身同等的审视,而不是边界没有意义。

如果我被利用了,我怎么知道?

说实话,靠沙箱自己的日志你不会知道。逃逸看上去就是监视器进程发出的普通文件操作——而同一个进程本来就正当地在写你的仓库。检测活在宿主机这一层:对凭据路径做文件完整性监控,以及出站日志。这正是检测智能体是否已被攻陷那一页详细论证的事。

该带走的通则是什么?

数一数你在隔离边界上开了几条通道,并假定每一条最终都会失效。然后把每条通道背后的东西缩小到「失效了也活得下来」的尺寸。隔离强度是整条周界的属性,不是它最强那堵墙的属性。

延伸阅读

本站相关:

信息来源: