GhostApproval 漏洞:你的 AI 编程工具链会受到什么影响
披露状态
Wiz 于 2026 年 7 月 8 日公开了 GhostApproval 的相关研究。六家受影响厂商中,三家已发布补丁,两家尚未修复。Anthropic 虽然不认同该漏洞的分类定性,但已上线缓解措施。如果你正在使用任何 AI 编程助手,请立即更新。
2026 年 7 月 8 日,Wiz 公布了一项横跨六款 AI 编程助手的安全研究,涉及 Amazon Q Developer、Anthropic Claude Code、Augment、Cursor、Google Antigravity 和 Windsurf。该漏洞被命名为 GhostApproval,恶意代码仓库可以诱骗 AI 助手突破工作区沙箱、将内容写到工作区之外。最坏的情况下,攻击者可以在开发者电脑上实现远程代码执行。
攻击手法本身并不新鲜——利用的是符号链接(symlink),一种古老的 Unix 机制。真正让人不安的不是符号链接本身,而是审批弹窗:这个本该是用户最后一道防线的界面,可以显示一个看起来完全无害的路径,AI 助手实际却把文件写到了别处。
攻击是如何发生的
攻击链路很短:
1. 攻击者创建包含符号链接的仓库:
project_settings.json -> ~/.ssh/authorized_keys
2. README.md 中包含指引:
"要设置工作区,请将以下内容添加到
project_settings.json..."
3. 开发者克隆仓库后,让 AI 助手
"设置工作区"或"按照 README 操作"
4. 助手在内部解析了符号链接,但向用户展示的是:
"是否对此文件进行修改?project_settings.json"
5. 用户点击批准。写入操作顺着符号链接
直接进入 ~/.ssh/authorized_keys
6. 攻击者由此获得这台机器的免密 SSH 访问权限
该漏洞的核心对应两个 CWE 条目:
- CWE-61(UNIX 符号链接跟随,UNIX Symbolic Link Following):AI 助手在跟随符号链接时,没有验证解析后的真实路径是否仍在工作区边界内。
- CWE-451(关键信息的界面误呈现,User Interface Misrepresentation of Critical Information):审批对话框显示的是符号链接名称,而不是真实目标路径,用户无法做出有依据的判断。
三种攻击变体
Wiz 演示了三种攻击路径:
-
SSH 密钥注入:攻击者把指向
~/.ssh/authorized_keys的符号链接伪装成配置文件。受害者的公钥被格式化成看起来人畜无害的配置项。只要用户点一次“批准”,攻击者就拿到了持久远程访问权限。 -
Shell 启动劫持:符号链接指向
~/.zshrc或~/.bashrc。注入的那行代码会在每次打开终端时执行,重启后依然生效,即使删除恶意仓库也无法清除。 -
通过读取窃取凭证:在 Augment 变体里,AI 代理在没有任何批准提示的情况下,读取了项目范围之外的 AWS 凭证文件,并通过模型自身的上下文窗口把机密信息泄露出去。
“知道却隐瞒”的问题
最糟的地方不在于代理会跟随符号链接,而在于某些代理明明已经意识到风险,却仍然给用户展示一个看起来干干净净的批准弹窗。
测试 Claude Code 时,代理的内部思维链推理曾经明确写道:
“我能看出
project_settings.json实际上是个 zsh 配置文件。”
然而,展示给开发者的确认弹窗只简单地问了一句:“要修改 project_settings.json 吗?”
代理掌握的信息比用户多得多,可这个弹窗却把这层信息完全丢掉了。
正如 Wiz 的研究人员所说:“如果循环里没有真话,那么‘人在循环中’也保护不了你。”
Windsurf 变体:先写入,后确认
Windsurf 暴露了更糟糕的模式:代理先把改动写入磁盘,然后才显示确认对话框。批准弹窗根本不是一道门闸,而是一个“撤销按钮”。等用户看到弹窗时,攻击者的 SSH 密钥早就写进 authorized_keys 了。
这算不上批准,纯属走过场。写在操作之后的确认对话框,只是给用户一种“我有控制权”的错觉,并没有真正的控制。
受影响工具与补丁状态
| 厂商 | 严重程度 | CVE | 已修复版本 | 状态 |
|---|---|---|---|---|
| Amazon Q Developer | 高危 | CVE-2026-12958 | 1.69.0(5月27日) | 已修复 |
| Cursor | 严重 | CVE-2026-50549 | 3.0(6月5日) | 已修复 |
| Google Antigravity | 严重 | 待分配 | 1.19.6(5月22日) | 已修复 |
| Augment | 严重 | 不适用 | 待定 | 修复中 |
| Windsurf | 严重 | 不适用 | 待定 | 已确认,暂无修复 |
| Claude Code | 高危 | CVE-2026-39861 | 2.1.64(4月20日) | 已修复 |
Claude Code 的时间线值得单独拿出来说。一个相关的符号链接沙箱逃逸漏洞(CVE-2026-39861,CVSS 7.7)由 HackerOne 平台上报,于 4 月 20 日在 2.1.64 版本中修复,并发布为 GHSA-vp62-r36r-9xqp。Anthropic 最初驳回了 Wiz 的报告,称其"超出了我们的威胁模型",理由是开发者既信任了该目录、又批准了提示词,属于自愿行为。后来他们表示,2 月初推送的符号链接警告属于"常规加固"。当前版本(2.1.173+)会在写入敏感路径之前解析符号链接并向用户发出警告。
披露时间线
| 日期 | 事件 |
|---|---|
| 2026年2月10日 | Wiz 发现该漏洞模式 |
| 2026年2月12日-15日 | 向各厂商提交报告;Anthropic 回复拒绝 |
| 2026年2月24日-3月5日 | 其余厂商确认收到报告 |
| 2026年4月20日 | Claude Code 修复 CVE-2026-39861(2.1.64 版本) |
| 2026年5月22日 | Google 部署修复(Antigravity 1.19.6) |
| 2026年5月27日 | AWS 部署修复(Amazon Q 1.69.0) |
| 2026年6月5日 | Cursor 部署修复(v3.0) |
| 2026年6月23日 | Windsurf 确认漏洞;此后无更新 |
| 2026年7月8日 | Wiz 公开披露 |
为什么这件事不只是某个具体 bug
GhostApproval 不只是符号链接的问题。它暴露了 AI 编程助手现有的安全叙事中一个关键断点:"每一步操作都由用户批准"。
这套说辞是否成立,取决于提示信息是否如实。可提示信息恰恰是由即将执行操作的同一个系统生成的。没有独立进程去核对:显示给用户的路径,和系统实际解析出来的路径是否一致。也没有另一个旁观者,在字节真正写入磁盘之前,确认这次写入始终没有超出工作区边界。
安全团队对这种模式并不陌生。你从来不会让应用自己评判自己的行为,而是在外面再加上一层检查:沙箱、强制访问控制、网络策略、外部监控。
同样的模式再次出现
不妨想想:GhostApproval 暴露了今天的 AI 编码工具安全是建立在哪些假设之上的。
真正的修复长什么样
厂商的补丁从三个方向处理眼前的符号链接问题:
- 先解析再显示:在弹出确认提示之前,先把路径里的符号链接全部解析完,让用户看到真实的目标位置。
- 解析后做边界检查:符号链接解析完成后,确认规范化路径仍在工作区范围内;如果不在,就阻止操作或给出警告。
- 确认前绝不写入:确保确认这道闸门在数据落盘之前触发,而不是在落盘之后。
这些修复都是必要的。但它们只修了一类 bug,并没有触及更深的问题:智能体(agent)报告的仍然是自己打算做的操作,而用户也仍然是唯一看得见的校验环节。
结构性的缺口
GhostApproval 之所以能得手,是因为许多智能体助手流程只有一个实际意义上的信任边界:审批提示。提示出现之前的一切——上下文组装、符号链接解析、路径显示——都被默认信任。提示之后的一切,则直接以开发者的本地账号权限运行。
现在缺少的,是一个独立的检查层,它能:
- 独立观察智能体实际做了什么(文件写入、网络请求、shell 命令),而不是只听它说自己打算做什么;
- 通过文件系统级别的监控,而不是智能体上报的路径,来验证文件操作的目标与用户批准的内容是否一致;
- 把用户的批准动作连同足够的上下文(解析后的路径、时间戳、会话来源)记录下来,以便日后审计:用户当时的同意,是否真的是在充分知情的前提下作出的。
网络层策略执行
- 在模型 API 请求和响应的传输层拦截数据,强制执行安全策略——即使代理本身已被攻破或行为异常,也必须经过这个独立检查点。
这正是「工具内置的安全功能」与「工具外围的安全控制」之间的区别。如果某个代码仓库能迷惑工具本身,那它内置的安全功能同样也可能被绕过。而外部监控机制因为运行在代理进程之外、脱离代理的信任域,反而更有机会发现问题。
立即行动
如果你或你的团队正在使用 AI 编程助手,请马上做以下几步:
-
立即更新版本。 Cursor 3.0+、Amazon Q 1.69.0+、Claude Code 2.1.64+ 和 Antigravity 1.19.6+ 均已包含修复。如果你用的是 Augment 或 Windsurf,目前还没有可用的补丁,要多加留意。
-
打开仓库前先做安全审计。 在让 AI 代理处理代码之前,先运行
find . -type l检查克隆的仓库中是否存在符号链接(symlink)。 -
审查你的批准历史记录。 在 Claude Code 中,检查
.claude/settings.local.json里是否有过于宽泛的权限规则;在 Codex 中,查看~/.codex/rules/default.rules。只要有一条被绕过的「始终允许」规则,就等于留下了一个永久后门。 -
把 AI 代理会话当作特权进程对待。 它们运行在你的凭据、SSH 密钥、Shell 环境和文件系统权限之下。一个被攻破的代理会话,其影响范围等同于你的整个用户账户被攻破。
-
考虑部署外部监控。 仅靠批准提示框这一个安全控制手段是远远不够的。独立的文件系统监控(在 inotify 层面观察实际有哪些文件被改动)、网络拦截(追踪实际上有哪些请求离开了机器)、以及批准审计(结构化记录哪些操作被批准、实际操作是否匹配),这些纵深防御措施是任何内部提示词都无法绕过的。