6款AI编程助手全部中招:GhostApproval漏洞如何骗过"人在回路"

6款AI编程助手全部中招:GhostApproval漏洞如何骗过"人在回路"

先说结论:你以为你批准的是编辑一个配置文件,实际上你批准的是往你的 SSH 授权列表里写入攻击者的公钥。这不是某一个工具的 bug,是整个 AI 编程工具行业的设计级缺陷。


7月8日,安全研究公司 Wiz 发布了一份报告,名字叫 GhostApproval。

报告里说了一件让所有用 AI 编程工具的人后背发凉的事:6款主流 AI 编程助手,全部存在同一个漏洞,攻击者可以利用它在你毫不知情的情况下获取你机器的 SSH 访问权限。

这6款工具是:Amazon Q Developer、Anthropic Claude Code、Cursor、Google Antigravity、Augment、Windsurf。

你大概率正在用其中至少一个。

一、攻击原理:一个符号链接就够了

不需要零日漏洞,不需要高级持久性威胁,不需要任何复杂的技术手段。攻击者只需要一个 Unix 系统里最普通的东西------符号链接(symlink)。

攻击过程分三步:

第一步:攻击者在 GitHub 仓库里放一个符号链接。

这个符号链接的名字看起来人畜无害,比如 project_settings.json。但它指向的目标是 ~/.ssh/authorized_keys------你的 SSH 授权文件。

第二步:你克隆了这个仓库,然后用 AI 编程助手打开。

AI 助手分析项目结构时发现了这个"配置文件",决定往里面写一些内容------比如添加一个配置项。这在日常开发中再正常不过了。

第三步:AI 助手弹出一个审批对话框,问你是否允许写入。

对话框上显示的文件名是 project_settings.json。你扫了一眼,觉得没问题,点击"接受"。

但操作系统跟随了符号链接。实际被写入的文件是 ~/.ssh/authorized_keys。攻击者的 SSH 公钥就这样被添加到了你的授权列表里。

如果你的机器开放了 SSH 访问,攻击者现在可以随时远程登录你的电脑。全程无异常提示,无告警,无弹窗。

另一种变体更隐蔽:符号链接指向 ~/.zshrc,攻击者的恶意代码被写入了你的 Shell 启动文件。不需要 SSH,每次你打开终端都会执行。

二、6款工具表现对比:谁最离谱

Wiz 对6款工具逐一做了测试。结果差异巨大------但不是好的那种差异。

最离谱的是 Augment。

Augment 连对话框都没有。Wiz 的测试中,AI 助手静默跟随符号链接读取了项目目录外的 AWS 凭证文件,然后直接把内容显示在了聊天窗口里:"Yes, this project has a hardcoded AWS key!"

写入操作同样静默。没有 "Allow/Deny" 按钮,没有 "Undo" 按钮,没有任何形式的确认。AI 助手自己识别出符号链接指向的是 zsh 配置文件,然后照样写入了恶意载荷。

第二名离谱的是 Windsurf。

Windsurf 的做法是:先写入磁盘,然后弹出 Accept/Reject 按钮。

你没看错。在你看到对话框之前,攻击者的 SSH 公钥已经在你的 authorized_keys 文件里了。 那两个按钮不是授权关卡,是撤销机制。而且你还不一定能注意到需要撤销------因为按钮上写的还是 project_settings.json

Cursor 和 Google Antigravity 表现类似。

两者的审批界面都显示了符号链接路径(project_settings.json),而不是解析后的真实路径(~/.ssh/authorized_keys)。用户点击"接受"时,后端跟随符号链接完成了写入。Cursor 已在 v3.0 中修复(CVE-2026-50549),Google 在 v1.19.6 中修复。

Claude Code 的情况最微妙。

Claude Code 的内部推理链在测试中正确识别出了文件异常 ------它知道这个"配置文件"实际上指向 SSH 授权文件。但这个关键信息没有被同步到用户界面 。用户看到的审批对话框上依然是 project_settings.json,没有任何警告。

AI 知道有问题,但没有告诉你。你的批准基于不完整的信息,因此实质上无效。

Claude Code 在 2026年2月5日的 v2.1.32 版本中已经加入了符号链接警告------这比 Wiz 提交报告还早了9天。但这个警告是否足够明显、是否在所有场景下都触发,Wiz 没有完全验证。

Amazon Q Developer 是响应最积极的。

Amazon 在 Language Server v1.69.0 中修复了符号链接逃逸漏洞(CVE-2026-12958),还额外修复了一个不需要符号链接就能窃取凭证的漏洞(CVE-2026-12957)。

三、"人在回路"安全模型是如何失效的

所有6款工具都声称自己有"人在回路"(Human-in-the-Loop)安全机制:AI 助手在执行敏感操作前需要用户明确批准。

但 GhostApproval 证明了这个模型有一个致命的前提假设:用户看到的信息和 AI 实际执行的操作是一致的。

当这个假设不成立时,整个安全模型就崩塌了。

Wiz 研究员 Maor Dokhanian 的一句话精确概括了问题的核心:

"当代理展示一种行为却执行另一种行为时,用户批准毫无意义。确认对话框从安全控制退化为形式。"

这不是一个哲学讨论。MITRE 的通用弱点枚举(CWE)体系中有一个正式编号------CWE-451:用户界面关键信息误导。这个标准明确把"在用户界面中歪曲关键信息"列为一种正式的安全弱点。

换句话说,这不是"功能不够完善",而是"安全设计有缺陷"。

四、Anthropic说"超出威胁模型"------真的吗?

6款工具的厂商回应分化明显:3家修复,2家沉默,1家争议。

Amazon Q Developer、Cursor、Google Antigravity 都在收到报告后发布了修复。Augment 和 Windsurf 承认收到了报告,但截至 Wiz 发文时没有发布补丁,也没有给出时间表。

Anthropic 的回应最特殊。他们说:这个场景"超出当前威胁模型"。

Anthropic 的逻辑是:开发者主动信任了一个仓库(session start 时选择了 trust),然后又主动批准了一个文件编辑操作。两步都是用户自己的决定,工具只是执行了用户的意愿。

这个说法看起来有道理,但忽略了一个关键问题:如果用户在批准时看到的信息是假的,他的"意愿"还是真实的吗?

你批准的是"编辑 project_settings.json",不是"写入 ~/.ssh/authorized_keys"。这是两件完全不同的事情。任何正常的开发者都不会把修改配置文件和添加 SSH 后门等同起来。

信息不对称是这里的核心问题。AI 助手知道(或应该知道)符号链接指向哪里,但用户不知道。在这个信息不对称下获得的"用户同意",在实质上是无效的。

值得庆幸的是,大多数厂商------包括 Google、AWS 和 Cursor------都选择将其视为漏洞并修复。Anthropic 的立场反而是个例。

五、这不是第一次了

GhostApproval 看起来像一个新发现,但实际上,同类漏洞在2026年已经出现了至少三次。

2026年5月:SymJack

安全公司 Adversa AI 披露了一个名为 SymJack(Symbol Jacking)的漏洞,影响包括 GitHub Copilot 在内的六款工具。攻击模式和 GhostApproval 几乎一模一样------利用符号链接欺骗 AI 助手。当时所有厂商最初都拒绝将其归类为漏洞,后来 Anthropic 等公司更新了防护。

2026年6月:DuneSlide

Cato AI Labs 以 DuneSlide 的名字独立发现了与 GhostApproval 相同的攻击模式,主要针对 Cursor 的沙箱机制。这个发现被 Wiz 的报告引用,Cursor 在致谢中同时提到了 Wiz 和 Cato AI Labs。

2026年6月:Miasma 蠕虫

这已经不是理论攻击了。归因于 TeamPCP 组织的 Miasma 蠕虫自2026年6月1日起活跃,通过恶意提交向 Microsoft Azure 的 GitHub 组织仓库植入凭证收集载荷,影响了73个仓库。虽然 Miasma 不完全使用符号链接手法,但它证明了利用 AI 代理配置文件进行攻击已经成为现实。

**三个独立团队在半年内发现了同一个结构性弱点。**这说明这不是个别厂商的疏忽,而是整个行业在设计 AI 编程工具时共同忽略的一个安全维度。

六、开发者怎么防

不需要搞一套完整的安全体系。以下三件事现在就该做:

第一,克隆仓库后检查符号链接。

在用 AI 编程工具打开任何外部仓库之前,花10秒钟扫描一下有没有符号链接。下面这段脚本只有50行,但能挡住 GhostApproval 类攻击:

python 复制代码
#!/usr/bin/env python3
"""GhostApproval symlink scanner - detect symlink traps before opening in AI tools."""

import os
from pathlib import Path
from dataclasses import dataclass

SENSITIVE_TARGETS = [
    "~/.ssh/authorized_keys", "~/.ssh/config", "~/.zshrc",
    "~/.bashrc", "~/.aws/credentials", "~/.gitconfig",
    "/etc/passwd", "/etc/shadow",
]

@dataclass
class SymlinkFinding:
    symlink_path: str
    resolved_target: str
    severity: str  # "CRITICAL" or "WARNING"

def scan_symlinks(project_root: str) -> list[SymlinkFinding]:
    """Scan project directory for dangerous symlinks."""
    findings = []
    root = Path(project_root).resolve()

    for path in root.rglob("*"):
        if not path.is_symlink():
            continue
        resolved = path.resolve()
        is_outside = not str(resolved).startswith(str(root))
        is_sensitive = any(
            str(resolved) == os.path.expanduser(t) or
            str(resolved).endswith(t.split("/")[-1])
            for t in SENSITIVE_TARGETS
        )
        if is_sensitive:
            findings.append(SymlinkFinding(
                str(path.relative_to(root)), str(resolved), "CRITICAL"))
        elif is_outside:
            findings.append(SymlinkFinding(
                str(path.relative_to(root)), str(resolved), "WARNING"))
    return findings

if __name__ == "__main__":
    import sys
    results = scan_symlinks(sys.argv[1] if len(sys.argv) > 1 else ".")
    if not results:
        print("[OK] No dangerous symlinks found.")
    else:
        for f in results:
            icon = "[!]" if f.severity == "CRITICAL" else "[?]"
            print(f"{icon} {f.severity}: {f.symlink_path} -> {f.resolved_target}")
        print(f"\n{len(results)} symlink(s) found. Review before opening in AI tools.")

完整版(含 CI/CD 集成、Git pre-commit hook、批量扫描)见 GitHub。

第二,审批文件操作时看解析后的路径,不看符号链接名。

这是 Wiz 给厂商的建议,但在厂商修复之前,开发者自己也要警惕。如果你在审批对话框里看到一个文件名,花一秒钟想想:这是真实路径还是符号链接?

第三,限制 AI 编程助手的文件系统权限。

不是所有项目都需要 AI 助手访问 ~/.ssh 目录。用容器、沙箱或文件系统权限控制来限制 AI 助手能触碰的范围。工具推荐用 Devbox 或 Distrobox 把 AI 编程环境隔离起来。

七、我的观点

分析完整个事件,我想说几点可能和大家不一样的看法。

1. 人在回路不是万能的

"人在回路"是当前 AI 安全领域最流行的设计范式:让人类成为最后一道防线,审批 AI 的关键操作。但 GhostApproval 暴露了这个范式的一个根本性缺陷------它假设人类在审批时拥有和 AI 同等的信息

现实中,AI 助手知道符号链接指向哪里,人类不知道。AI 助手的内部推理链可能已经识别出异常,但这些信息没有传递到审批界面。在这种信息不对称下,人类的"批准"不过是一个没有意义的点击动作。

未来的安全模型不能只靠"加一个审批按钮"。需要做到:要么让人类看到 AI 看到的所有信息,要么不要求人类为 AI 的决策背书。

2. 这比 Claude Code 后门更危险

我之前分析过 Claude Code 的 Unicode 隐写后门事件(那是 Anthropic 主动在产品里藏东西)。但 GhostApproval 的危险程度其实更高------因为这次不需要 AI 公司是恶意的

Claude Code 后门需要 Anthropic 主动作恶。而 GhostApproval 是外部攻击者利用 AI 工具的设计缺陷。你不需要信任 AI 公司,你只需要信任你克隆的那个 GitHub 仓库------而这在开源世界里几乎不可能完全避免。

这意味着,即使所有 AI 公司都完全值得信任,只要 AI 编程工具的"人在回路"设计不改进,这类攻击就会持续存在。

3. 行业需要"安全默认值"

Wiz 在报告最后提出了三条建议,本质上是要求 AI 编程工具厂商做到三件事:

  1. 在显示审批对话框之前先解析符号链接,显示真实路径
  2. 如果解析后的路径在项目目录之外,明确警告
  3. 永远不要在用户明确授权之前写入磁盘

这三条都不难实现。难的是让整个行业接受这些作为默认行为,而不是可选的安全加固。

好消息是,Google、AWS、Cursor 已经选择了修复。坏消息是,Augment 和 Windsurf 还在沉默,Anthropic 还在争议。

4. 开发者需要改变习惯

在 GhostApproval 之前,克隆一个 GitHub 仓库然后打开 IDE 是最普通的开发动作。但现在,如果你用 AI 编程助手,你需要在打开仓库之前多走一步------检查符号链接。

这不是偏执。这是2026年的基本开发素养。


本文是「AI Agent 安全」系列的第二篇。第一篇《Claude Code 为什么会被大厂禁用?》讲的是 AI 工具主动伤害用户的案例,这一篇讲的是 AI 工具被外部攻击者利用的设计缺陷。两篇合在一起,覆盖了 AI 编程工具安全威胁的两个维度。

本文基于 Wiz Research 的公开报告、MITRE CWE-451 标准、以及各厂商的公开回应撰写。技术细节经交叉验证,观点为作者独立判断。