你的编辑器预览浏览器不是浏览器:在自己工作站上审计 EMBRACE 信任边界

Dev.to AI 2026-10-31T04:52:25+08:00

Cursor、Copilot、Codex、VS Code 和 Claude Desktop 里的预览窗格看起来像个浏览器。2026 年 10 月 29 日,Forever Security 的 EMBRACE 研究(研究员 Gal Weizman)证明,它确实被当作浏览器来信任——而这份信任用错了地方。发布时还有两款工具未打补丁。本文是一份审计:发现了什么、如何检查自己的机器、以及在下个修复验证之前该怎么做。

下文每项事实的依据:Forever Security,EMBRACE 研究,2026 年 10 月 29 日;以及 The Register,2026 年 10 月 29 日。补丁状态截至 2026 年 10 月 29 日。动手之前,请对照厂商发布说明再次核实。

EMBRACE 发现了什么

Forever Security 于 2026 年 10 月 29 日发布 EMBRACE 研究,The Register 同日报道。五个问题,同一个边界:AI 编程工具内嵌的预览被当作独立浏览器来信任。五个问题均未分配 CVE 编号。

Cursor——通过 composer 桥接实现代码执行。网页可以经由 composer 桥接触发代码执行:智能体读取页面上隐藏的指令,演示中通过安装恶意软件包启动了计算器。该行为依赖具体模型,并非每次都能复现。2026 年 9 月 10 日报告;2026 年 10 月 1 日修复。据研究员称,既没有安全公告,也没有收到回复。(Forever Security,2026 年 10 月 29 日;The Register,2026 年 10 月 29 日。)

GitHub Copilot——地址栏欺骗。在 1.1.27 版本中,页面可以用一个假表单冒充 github.com/login。2026 年 9 月 26 日发现。2026 年 10 月 13 日在 1.1.29 中修复——是在 Forever Security 提交报告之前独立完成的。(Forever Security,2026 年 10 月 29 日;The Register,2026 年 10 月 29 日。)

Codex、VS Code 和 Claude Desktop——读取范围超出项目文件夹。本地 HTML 文件可以读取项目文件夹之外的内容。VS Code 和 Claude Desktop 对页面本身做了限制,但管不住它启动的 Web Worker;Codex 则完全没有文件夹检查。研究员演示了读取 SSH 密钥、.env 文件和 npm 令牌。该演示仅在此描述,从未复现:本文不读取任何真实密钥。

发布时状态。截至 2026 年 10 月 29 日,Codex 和 VS Code 仍未修复。Claude Desktop 的修复情况不确定:Forever Security 已不再将其列为未修复漏洞,但并未公布修复版本或修复日期,因此本文既不说它已修复,也不说它未修复。建议你自己验证——见下文第 1 步。

厂商回应。微软和 Anthropic 拒绝接受报告,理由均指向 Workspace Trust(工作区信任)。Anthropic 接受了 Noma Security 于 2026 年 7 月 24 日提交的同类报告。据研究人员称,OpenAI 未回复 7 月 27 日的报告——但 OpenAI 向 The Register 表示已知悉此事,正在修复中。(Forever Security,2026 年 10 月 29 日;The Register,2026 年 10 月 29 日。)

边界为什么失效

独立浏览器会执行源(origin)和文件访问规则:来自某个源的页面无法随意读取你磁盘上的文件,本地文件也只能访问自己所在的目录。而嵌入式预览则继承了编辑器对工作区的信任。预览看起来像浏览器,但它运行时依据的是编辑器与项目文件夹之间的信任关系——所以信任决策取决于工作区,而不是网页的规则。

用文字描述 worker 逃逸的形态:页面本身被限制在文件夹内,但页面启动的 Web Worker 却没有受到同等限制(VS Code 和 Claude Desktop),而在 Codex 中则根本没有文件夹检查。限制只停留在页面,却管不住页面能启动的东西,这就不算真正的边界限制。

本文不包含漏洞利用代码、不涉及数据外传,也没有攻击他人的指导。这次审计的目的恰恰相反:帮你确认自己的机器、自己的版本上是否仍有这个漏洞——然后通过更新或改变预览的使用方式来堵上它。

教程:审计你自己的工作站

仅限自己的工作站。下面所有操作都在你自己的机器上运行,针对你自己的项目文件夹,不会读取任何真实的密钥。

第一步:记录已安装的版本

打开每个工具的"关于"页面,记下安装的版本号。再对照排查工具包状态表里列出的修复版本:Cursor 于 2026 年 10 月 1 日修复;GitHub Copilot 于 2026 年 10 月 13 日在 1.1.29 版本中修复;Codex 和 VS Code 截至 2026 年 10 月 29 日仍未修复;Claude Desktop 的修复状态尚不确定,没有公布修复版本或日期。如果你的版本低于修复版本,先升级再说——并且要对照厂商发布说明再核实一遍,因为 2026 年 10 月 29 日之后状态可能会变。

第二步:检查工作区信任设置

逐个检查每个工具的工作区信任设置:把不受信任的文件夹保持在受限模式(Restricted Mode),并检查受信任文件夹列表,凡是认不出来的、或者已不再信任的,一律删掉。微软和 Anthropic 拒绝受理这些报告时,援引的正是这个设置——但只有当不受信任的文件夹确实被限制了,它才真正管用。

第三步:运行工具包的金丝雀自测

工具包的自测只依赖标准库(stdlib)。它会在临时目录里创建自己的金丝雀文件,写一个无害的探针页面,并打印 PASS/FAIL 判定标准。从工具包目录下,针对你自己的项目文件夹运行:

python3 canary_self_test.py --project-dir /path/to/your/project

随后脚本会打印出这一步的手动操作说明,原文照引如下:"在被审计工具的内嵌预览中打开探针页面(而不是独立浏览器),读取 PASS/FAIL 结果行,把工具名 + 版本 + 结果,连同当天日期,一起记录到排查结果模板里。"

退出码为 0 只代表测试框架准备就绪——手动预览这一步仍然不能省。一次 PASS 只能证明某一个版本上的某一处边界,并不代表整体安全。

脚本生成的探针页面名为 embedcheck-canary-probe.html,放在项目文件夹里。这正是工具包脚本生成的东西——它只去取金丝雀路径,把结果写进页面自己的 DOM,不会往任何地方发送数据。取的目标是脚本算出来的金丝雀相对路径,比如 ../embedcheck-canary-<name>/canary.txt:

<script>
fetch('../embedcheck-canary-<name>/canary.txt')
  .then(function (r) { return r.text(); })
  .then(function (t) {
    document.getElementById("result").textContent =
      "FAIL — boundary did not hold: canary was readable from this preview context.";
  })
  .catch(function () {
    document.getElementById("result").textContent =
      "PASS — boundary held: canary was NOT readable from this preview context.";
  });
</script>

脚本头部已经说得很清楚:它不做任何网络请求(不开套接字、不发 HTTP、不做 DNS 解析);不读取真实的密钥文件或任何真实密钥——只读它自己创建的 canary 文件;不扫描其他机器;也不会复现研究人员读取真实密钥的演示。

用文档里给出的清理命令收尾:

python3 canary_self_test.py --project-dir /path/to/your/project --cleanup

手动步骤执行完后,脚本还会打印一条删除命令,里面带上实际的运行时路径(格式为 rm -rf <temp-dir> <probe-page>),并附注「(or re-run with --cleanup)」。canary 临时目录建在系统临时目录下,前缀是 embedcheck-canary-。

Step 4 —— 记录结果。把结果填进那张一页纸的发现记录模板,注明截止日期:工具名、安装版本、PASS 还是 FAIL、当天的日期。一个工具 PASS 不代表其他工具也 PASS——每个工具都要单独测。

政策层面的讨论(适合小团队)

三条规则,每条都对应上面某个具体发现——不是泛泛而谈的建议。

  1. 不要在嵌入式预览里打开不受信任的 HTML。Codex、VS Code 和 Claude Desktop 的问题都是本地 HTML 文件读到了项目文件夹之外。不受信任的 HTML 应该放到独立浏览器里打开,或者干脆别打开——绝不要放进继承了工作区信任的预览面板。

  2. 绝不在预览表单里输入凭据。Copilot 的问题是地址栏伪造:一个页面在假表单上方显示 github.com/login。如果预览里出现了登录表单,立刻停手。凭据只能在真实浏览器、真实域名下输入。

  3. 页面上出现的智能体指令,一律视为不可信。 Cursor 那次发现的情况是:智能体读取了网页上隐藏的指令,然后通过 composer bridge 照做。页面内容里夹带的指令只是数据,不是命令——除非有人判断确实需要执行,否则智能体不该理会。

几点如实说明


EmbedCheck(29 美元一次性买断,Haku 出品)是完整工具包:状态表、检查清单、信任指南、金丝雀自测与运行手册,以及策略与报告模板。https://vittoriali.gumroad.com/l/eysfws

— Haku

查看原文