那个关掉了 Cursor 沙箱的注入
2026 年 7 月 1 日,Cato AI Labs 披露了 DuneSlide:Cursor 中的两个严重漏洞(CVE-2026-50548 与 CVE-2026-50549,CVSS 均为 9.8),其中一个搭着 MCP 工具结果或网页搜索片段而来的提示词注入,驱动 run_terminal_cmd 工具和一个符号链接兜底逻辑,去覆写 Cursor 自己的沙箱辅助程序。守卫从内部被悄悄关掉,而下一条命令便以开发者的身份运行,触手可及编辑器登录的任何云或 SaaS。无需用户交互,已在 Cursor 3.0 中修复。这是一个关于边界应当身处何处的故事:在 Bromure Agentic Coding 中,同样的逃逸落进一台一次性 VM 里,逃逸出来的 shell 在本该是真令牌的地方只找到被换掉的桩值,而 PromptGuard 早在模型据以行动之前,就在线缆上给那段不受信任的内容打了分。
DuneSlide 并没有冲破 Cursor 的沙箱。它劝动 Cursor 自己的代理去 覆写那个负责执行沙箱的小二进制文件,于是守卫从内部陷入了沉默。 一道与它所看守的代码活在同一个进程里的边界,是一道代码伸手就能 够到的边界。
一位开发者请 Cursor 去接一个新集成,并把它指向某个厂商的文档,或者 连上一台 Model Context Protocol 服务器,好让代理能拉取实时数据。MCP 就是那个让编码代理去调用外部工具、并读取其结果的插头。Cursor 抓取 页面,读取工具的输出,再把两者都折叠进它据以推理的上下文。就在那段 返回的文本里的某处,坐着一句开发者从未写过的话,冲着模型而非人类 说去。代理把它当成一条指令读了下来,并动了手。
2026 年 7 月 1 日,Cato AI Labs 披露 了由此搭建起来的这条链条,而 The Hacker News 在同一天做了报道。两个漏洞,CVE-2026-50548 与 CVE-2026-50549, 双双被评为 10 分中的 9.8 分。投递载体,是代理早已替你读进来的 不受信任内容:一个 MCP 工具结果、一段网页搜索的片段。没有对话框, 没有点击,没有任何用户交互。
DuneSlide 干了什么。
Cursor 把它的代理生成的命令,跑在一个本地沙箱里,而一个辅助二进制
文件决定这个沙箱允许什么。第一个漏洞藏在 run_terminal_cmd 里,
也就是代理用来运行 shell 命令的那个工具。这个工具接受一个
working_directory 参数,而注入把它设成了一条指向 Cursor 自己
文件的路径。代理顺着这条被夹带进来的指令,覆写了坐落在
/Applications/Cursor.app/.../helpers/cursorsandbox 处的那个辅助
程序。第二个漏洞是 Cursor 解析符号链接方式里的一个兜底逻辑:当
符号链接检查失败时,Cursor 会信任该快捷方式在项目内的路径,结果
照样写到了项目之外,落到了同一个辅助程序上。
无论哪条路,结果都是一件事。那个决定一条命令是否被约束的二进制文件, 被换成了一个什么也不约束的。代理接下来跑的那条命令,便以开发者的 身份、在沙箱之外执行,触手可及编辑器登录者所能够到的一切:云控制台、 SaaS 仪表盘、会话早已能碰到的那些仓库。Cursor 在 3.0 版里修复了 这两个漏洞。之前的每一个构建都暴露在外。
边界坐落在它所看守的那间屋子里。
再读一遍这条链条,锋利的那一处并不是符号链接的把戏。而是守卫所处的
位置。那个决定一条命令是否被约束的辅助程序,坐落在代理所编辑的项目
同一块磁盘上,处在与代理相同的信任域内,被代理用于日常工作的同一个
run_terminal_cmd 就能够到。沙箱和它所监管的代码,以同一个用户身份、
在同一台机器上运行,两者之间只隔着同一套文件系统。给代理写一个文件
的能力,让攻击者去挑写哪个文件,而他们挑中的那个文件,就是守卫。
这就是今年编码代理安全里反复出现的那种失效,我们已经用别的形状把它 写过:一个代理能读的凭据,也是一个被攻陷的依赖能读的凭据,见 那个守着钥匙的沙箱, 而一个代理能关掉的控制,从来就算不上一个控制,见 为什么 Bromure Agentic Coding 不是一个沙箱。 DuneSlide 是同一课,只不过发生在沙箱二进制文件本身这一层。一个进程内 的守卫会一直保护你,直到它所寄居的那个进程决定去编辑它。
同样的攻击,隔着一层 hypervisor。
Bromure Agentic Coding 把边界放在代理写不到的地方。代理、它派生出的 那些 shell、它调用的那些工具,以及那些工具所运行的任何代码,都活在 一台拥有自己 Linux 内核的一次性虚拟机里。VM 发出或读入的每一个字节, 都要穿过一个 proxy,它运行在 macOS 宿主上,位于客户机之下,在 hypervisor 的另一侧。那个 proxy 是同一个地方,而它干着好几件活。 把 DuneSlide 拿来对着它重放,每一步都会撞上其中之一。
从逃逸说起。注入照样到来,代理照样运行 run_terminal_cmd,两个 CVE
也照样触发。覆写落到了客户机自己的文件上。Mac 的磁盘、它的
/Applications、它的 Keychain 都不在 VM 的世界里,所以从客户机内部
的一个符号链接,通不到宿主上的一个二进制文件。爆炸半径是一台你几秒钟
就能删掉再重建的机器。
再看那一步收益——伸向云和 SaaS 的触手。攻击就是冲着这份价值而来的,
而它却扑了个空。真令牌留在宿主上。VM 里装着的是桩值:形状对得上、
在公共互联网上却毫无意义的凭据文件。当代理发起一个需要真正机密的
调用时,宿主 proxy 会在线缆上把桩值换成真令牌,再从响应里把它换回来。
一个逃逸出来的 shell 跑 env | grep TOKEN 或读 ~/.aws/credentials,
找到的是占位符。一个真凭据存在的唯一时刻,是在代理为真实工作发起的
一个请求里面,而一个会改变状态的调用,会在离开之前停在边界处,等宿主
上的一次询问。取包也穿过同一个 proxy,并在进来的路上被扫描。一条线,
好几件活,全都在代理之下。
逃逸落在客户机里。
两个 CVE 在 Bromure 下照样触发。覆写打在一台拥有自己内核的 一次性 VM 内部的文件上,而 hypervisor 不给客户机任何能够到宿主的 系统调用。你重建 VM,损害就随之而去。
它想要的那个令牌从来就不在那里。
DuneSlide 的目标是开发者的云和 SaaS 访问权。那些机密坐落在宿主上, 而 VM 携带的是在互联网上毫无意义的桩值。逃逸出来的 shell 去 grep 令牌,读到的是占位符,于是那一步收益落了空。
PromptGuard 先读一遍线缆。
上面这份保证不需要任何分类器就成立:VM 边界困住逃逸,令牌置换饿死
收益,不论模型做什么。Bromure 在同一个 proxy 上再加一层,正对着
DuneSlide 所用的那个载体。注入行进在代理会摄入的内容里——一个 MCP
工具结果,或一段网页搜索片段——而那段内容会在模型读到它之前先穿过
宿主 proxy。若启用,PromptGuard 就在那里给它打分。第一阶段是 Meta
的 Llama Prompt Guard 2,盯着工具输出和网页抓取,找出那些把模型当成
指令对象来说话的文字。而那些被代理当成常设命令来对待的规则文件,
CLAUDE.md 及其同类,则改由一个微调过的 ModernBERT 分类器来处理,
因为一个本就意在全是指令的文件,需要一个给伤害而非注入打分的模型。
按配置文件而定,Bromure 会记录这次命中、把它展示给你以作决断, 或者在模型看到那段被投毒的片段之前就把它拦下。位置就是关键,而这 和它之下那些层的道理是同一个:一个已经吞下了注入的代理,不能被 指望来举报它,所以检查跑在边界的另一侧,在代理的劝说够不到的地方。 我们把完整的流水线写在了 Bromure 如何检测恶意提示词里, 也在 那条指令不是他下的一文里, 看着同一类攻击搭着一条命令的输出溜了进来。
DuneSlide 已在 Cursor 3.0 中修复,而今天去更新是正确之举。它背后的 那个模式并没有被修复,因为它不是一个单独的漏洞。任何一个把自己的 约束跑在自己进程里的编码代理,都只离一句有说服力的话就能编辑那道 约束。那个能挺过下一个换了名字的 CVE 的做法,是把守卫、凭据和审计 轨迹,都留在一条代理写不到的线的另一侧。Bromure Agentic Coding 把那条线画在了 hypervisor 上。它免费、开源,今天就已发布。