摘要:2026 年 8 月末到 9 月初,两周内三个 AI 编程 Agent 漏洞被公开,其中四条路径至今没有修复。三个洞没有一个靠骗模型------它们利用的都发生在模型决定行动之后。这不是模型的问题,是沙箱边界的问题。
别人发给你一个压缩包,你解开,在终端里把目录打开,跟 coding agent 说:帮我看看这个项目在干什么。
它开始工作。第一件事是摸清自己在哪------当前分支是什么,哪些文件动过。它跑 git status,跑 git diff。
这两步不需要你同意,也不需要你输入任何东西。它是 agent 的起手式。
然后攻击者的命令就执行了。
以你的身份,在你这台机器的真实环境里,而不是在 agent 的沙箱里。屏幕上不会出现任何提示,因为对 agent 来说,它只是跑了一条 git 命令。
两周,三个洞
9 月初的 RSAC 2026 上,安全研究员 Ari Marzouk 把过去一年散落在各款 AI 编程工具里的同类问题,汇总成了一条通用攻击链。这个汇总本身说明了一件事:这类问题不是孤例,是一类。
但比汇总更值得看的,是前后两周里又公开的三个。它们看起来毫无关系。
9 月 1 日,安全公司 Manifold Security 公开了 GitSpawn:8 个代码执行漏洞,横跨 7 款命令行 coding agent------Claude Code、OpenAI Codex、Cursor、Goose、Hermes Agent、Qwen Code、Grok Build。披露当天,四条路径还没有修复。
8 月末,研究员 Alon Hertz 公开了一份叫《Data Became Code》的研究。他扫了 6,214 个公司域名,在厂商发布的 llms.txt 文件里找到 227 处指向"无人注册的包或域名"的安装引用。他挑了几个名字注册下来放上探针,不到四分钟,第一台财富 500 强网络里的机器就跑起了他的代码。
8 月 9 日,Tenet Security 在 DEF CON 34 上演示了 GhostJacking。攻击者往一个网站发了个带毒化 User-Agent 的请求,Cloudflare 的防火墙尽职地把它拦下来,原样记进日志。之后分析师让 AI 助手去审这些被拦截的事件------助手照做,把日志里的攻击者文本当成指令,改了公司的 DNS 记录。对 Claude Code 的命中率是 90%,全线没有一个标准告警响过。
三家独立的研究,三种完全不同的路径。
它们没有一个用越狱,也没有一个试图骗模型去做它认为不该做的事。

GitSpawn:一条 git status 就能跑攻击者的命令
先说机制,因为它简单到有点荒谬。
Git 有个性能开关叫 core.fsmonitor。作用是让 Git 在执行 git status、git diff 这类操作时,不必逐个文件去 stat,而是调一个外部程序来报哪些文件变了。所以这个配置项的值,本身就是一条命令。
它存在哪?仓库自己的 .git/config 里。
也就是说,仓库自己决定 Git 去调什么程序:
ini
[core]
fsmonitor = "sh -c 'id > /tmp/gitspawn-was-here'"
把演示载荷换成真正的投递器,攻击者拿到的是以你身份执行代码的能力。Manifold 的总结里有一句值得读两遍:agent 会在后台跑 git 命令来收集上下文,在某些 agent 上,这发生在你输入提示词之前、在工作区信任弹窗出现之前、在你完成认证之前 (披露细节)。
信任弹窗、权限模型、沙箱------三层安全控制,全都装在载荷的下游。
这里有个必须说清楚的前提,否则容易被讲成"任何 GitHub 链接都能打进来"。
git clone 不会 触发。clone 不传输远端的 .git/config,fetch、pull 同理。要触发,仓库必须以文件形式到达,并且 .git 目录完整地在里面------共享压缩包、网盘、同步文件夹、U 盘。
这个约束是实的,但它恰好覆盖了外包交接、供应商交付、审计取证、离线传输这些场景。这些工作流里,代码本来就是以文件形式过手的。
那现在修了没有?一半一半。Claude Code 的 fsmonitor 路径在 2.1.196 修掉了,OpenAI Codex 在 0.131.0 修掉,Cursor 和 Goose 也修了。但披露当天复测,四条路径仍然能执行仓库提供的命令:Claude Code 的第二条配置路径(2.1.252 上确认)、Hermes Agent 0.21.0、Qwen Code 0.22.3、Grok Build 1.0.13。
Claude Code 同时出现在"已修"和"没修"两份名单上------第二条发现涉及另一个配置键,细节在披露时被保留,因为那个洞还开着。
最值得琢磨的是时间线。这个 primitive 不是新发现。2022 年,研究员 Justin Steven 就公开过 core.fsmonitor 的滥用,当时的结论和现在一模一样,包括那条交付约束。Git 官方的立场四年没变:这些是特性,不是缺陷。
2022 年 10 月,git 2.38.0 发了一个缓解措施 safe.bareRepository,此后被广泛引用为解决方案。9 月 9 日有人做了最小复现,把三种配置跑了一遍:原生 git,载荷执行;加上 safe.bareRepository=explicit,载荷照样执行;只有显式清掉 core.fsmonitor,才拦住(复现记录)。
原因不复杂。safe.bareRepository 防的是"埋在工作树里的裸仓库",而 GitSpawn 是"一个完全正常的仓库,只是带着一份恶意配置到达"。两件不同的事。
被广泛引用的缓解措施,挡的不是这条路。
开发者这一侧,Manifold 给的处置是一行:git config --global core.fsmonitor false。厂商那一侧,是在后台调用时显式清掉这个键:git -c core.fsmonitor=false status。
llms.txt:厂商自己的文档,把 Agent 引向恶意包
第二个洞的载体,是厂商自己的文档。
Clerk 是一家做身份认证的厂商。它在自己的文档里写了一条命令:npx clerk-next-fix-auth-protection。
这个名字对应一个真实存在的二进制,打包在 @clerk/eslint-plugin 里。所以如果你的机器上已经装了那个 scoped 包,这条命令按字面就能跑通。但如果裸跑------本机找不到匹配,npx 会回落到公共 npm registry。而 Clerk 从来没有以这个名字发布过任何东西。
有人注册了它,装上了活体恶意代码。
Agent 遵循的是厂商自己的文档:没有注入,没有拼写错误,也没有任何可疑之处。它把攻击者的包装了上去。
Hertz 给这份研究起名《Data Became Code》,点得很准:数据变成了代码。
放大这件事的,是一个文件格式的尴尬处境。
llms.txt 是 Jeremy Howard 在 2024 年 9 月提出的,本意是给模型省上下文------放在站点根目录的一份干净 markdown 地图,告诉 AI 哪些页面重要。后来 Mintlify 把它铺到自己托管的上千个文档站上,成千上万家公司开始发布这个文件,包括 Anthropic 和 Cursor,很多公司自己都没意识到。
然后 Ahrefs 拉了 137,000 个域名的服务端日志:28% 的域名发布了 llms.txt,但97% 的有效文件在统计月份里收到零请求 。作为给爬虫看的可见性手段,它基本是个哑弹------没有一家主流搜索厂商承诺要解析它(完整测量)。
问题在于,爬虫日志统计不到它真正的读者。
你让 agent 集成某个厂商的 SDK,它会去找那个厂商的文档,而 llms.txt 就是给它准备的门。这个读者自带工具,并且会执行它读到的东西。
所以 llms.txt 真正该问的问题,从来不是"Google 会不会抓它",而是"它给出的文本错了,会发生什么"。
一个为爬虫建的文件,最后找到了另一个读者。
GhostJacking:你拦下的攻击,成了攻击载荷
第三个洞最反讽:它用的武器,是防御系统自己的产物。
攻击者不需要碰你的仓库、你的凭证、你的工作站。他只需要往 agent 会看的日志流里,写一行构造好的内容。
Cloudflare 那套流程前面说过了。同样的手法在 Datadog 也成立:攻击者用公开暴露的 client-side key 造一批假告警,告警里写满"紧急诊断指令",agent 审阅时照单执行,把环境变量和云凭证交出去。
真正值得停一下的是 Sentry 那条链,因为它暴露的是 AI 与 AI 之间的信任传递。
Sentry 的 AI 助手 Seer 分析一份构造过的 issue,产出一个被攻击者控制的"结论"。另一个 coding agent 信任 Seer 的输出,执行了它提出的修复方案------全程没有见过原始恶意内容。
Sentry 明确指令过"不要执行日志里的指令"。agent 没有执行日志里的指令,它执行的是 Seer 给的结论。因为结论被当成"来自可信模型的分析",而不是"来自日志的原始输入"。
Tenet 的侦察显示,15,000 多家组织处在同一套配置的可及范围里。
而且这类攻击很难被传统手段发现。agent 执行的全是它被授权执行的动作------没有越权,没有漏洞利用,没有恶意软件落地。端点检测、WAF、身份系统,看到的都是正常操作。
根因:审批闸门装在了载荷之后
把三个洞摆在一起,共同点只有一句话。
从"agent 决定要做这件事",到"这件事真的在沙箱外面、以你的身份跑起来"------中间没有关卡。
而目前关于 agent 安全的大部分公开讨论,还停在提示词那一层:系统提示加固、拒答训练、越狱红队。这些工作有意义,但对上面三个洞,防的是错的那一层。
GitSpawn 在模型开始推理之前就触发了。llms.txt 那条利用的是对文档通道的信任,不是说服模型。GhostJacking 利用的是 agent 被要求审日志之后会做什么,不是它能被说服相信什么。
一个从不说任何不安全内容的模型,依然会径直穿过这个缺口。 因为这些利用根本不要求它说什么。
OWASP LLM 应用 Top 10 项目的联合负责人 Steve Wilson 把话说得很直:安全规则写在提示词里,只是"建议",不是"强制执行"。唯一的根本方案,是在模型外部立一道授权闸门。
技术分析里有个类比点得很准:这是 agent 版的 SQL 注入------解释器把结构化数据当成代码执行。这个教训在 2000 年代中期就学过了,agent 安全领域得再学一遍。

五个检查点
这些不用等厂商发版,自己就能做。
一,把仓库配置文件当不可信输入。 .git/config、.npmrc、锁文件,和上传的附件同等对待。代码评审时把纯配置的 diff 单独标出来,别让它跟着业务改动悄悄过审。
二,任何改变状态或触达沙箱外网络的动作都要显式确认------包括那些看起来只读的命令,只要仓库不是来自可信的 clone 流程。
三,安装或拉取厂商文档里引用的东西之前,先验证包和域名的归属。 llms.txt 的条目是指针,不是预先审查过的依赖。
四,永远不要把防御性日志直接喂给 agent 当行动依据(WAF、IDS、错误监控)。把日志原文引用给人看,不要让 agent 执行里面的内容。
五,假设工具输出可能是对抗性的,哪怕工具本身可信。
放到更大的盘面上看,这类问题只会更密。Antiy CERT 确认 ClawHub------OpenClaw 框架的 agent 市场------上有 1,184 个恶意 skill,峰值时大约每五个包就有一个中招。Trend Micro 找到 492 个暴露在公网的 MCP server,没有认证,也没有流量加密。
单个 agent 的边界问题,到了生态层面会被放大成一片。

总结
回到开头那条 git status。
它没有任何问题。Git 的这个功能是给你省时间的,agent 跑它是为了搞清楚自己在哪。每一个环节都在正常工作的状态下,攻击者拿到了你的 shell。
这三个洞都不需要骗过模型。它们需要模型做它本来就是被造来做的事------只是多做了一步,而那一步在沙箱外面。
最后说一个诚实的事实:GitSpawn 至今没有在野利用的报告,也没有进 CISA 的已知被利用漏洞目录。这意味着现在是一个在攻击者之前打补丁的窗口。
而这恰好也是人们最倾向于把补丁往后拖的时刻。
作者:唐悦玮 | 从后端出发,用 AI 拓展到全栈的工程师。