AI

你没跑的那条 git,已经以你的权限跑完了(中英切换)

你没跑的那条 git,已经以你的权限跑完了。

你打开文件夹,还没敲提示词,agent 已经在后台跑 git status / git diff 采上下文。有的产品甚至在工作区信任弹窗之前、在你登录之前就跑了。这些调用被当成「只读、低风险」——不进工具审批,也不进沙箱。

问题不在模型,在它脚下那根管子。Git 有个合法性能开关 core.fsmonitor:刷新索引时,让外部程序告诉它哪些文件变了。这个设置读的是仓库自己的 .git/config。仓库可以写死一行命令;agent 一摸索引,命令就以你的权限在宿主机上跑完——屏幕上什么都没有。

你没跑的 git → 已经以你的权限跑完

GitSpawn:不是注入,是你底下的 git

Manifold Security(2026-09-01)把这类洞叫 GitSpawn:七个主流 coding agent、八项发现。到披露日,Claude Code(core.fsmonitor)、Codex、Cursor、Goose 已修至少一条路径;Qwen Code、Grok Build、Hermes,以及 Claude Code 的第二条(ultrareview)仍可利用CSA 2026-09-04 纪要把表钉死:Goose 有 CVE-2026-72718(CVSS 7.0),Codex 有 CVE-2026-19592 / 19593,Hermes 由 VulnCheck 独立编号 CVE-2026-71963——厂商六次联系仍未分流。

攻击链干净得吓人:不需要提示词注入,模型甚至看不到 payload。交付不是 git clone(clone 不带对方本地 config),而是带 .git 目录的 zip / 网盘 / U 盘——同事互传项目的日常方式。agent 自己的上下文采集 spawn 了 git;git 读到恶意 fsmonitor;命令在沙箱外、审批外、以你的身份跑完。

信任弹窗挡不住「你没点过的那一下」

我们以为危险的是模型想跑的 shell。GitSpawn 告诉我们:真正危险的是产品自己为了显得聪明,在你开口之前就跑掉的那几条「只读」命令。信任弹窗、工具审批、沙箱——全在更上层。底下那根管子没消毒,上层再严也白搭。

同一年里 GhostApproval、Sonar 的 trust-before-click、Cursor 的 git.exe 零日,反复打同一块板:仓库自带的元数据默认可信。GitSpawn 只是把这块板钉得最死——合法配置项,合法 git 行为,非法的是「agent 不消毒就摸」。

今晚只做一件事

打开你最近收到的、不是 clone 来的那个项目目录。先别开 agent。在目录里跑:

git config --get core.fsmonitor

有输出——先搞清楚那是谁写的,再谈打开 Claude / Cursor / Codex。厂商侧:上下文采集必须显式 git -c core.fsmonitor=false …,别再信任仓库自带的 config。

你没跑的那条 git,已经以你的权限跑完了。先查 .git/config,再让 agent 摸仓库。

The git you didn't run already ran as you.

You open a folder. Before you type a prompt, the agent already ran git status / git diff to gather context. On some products it fires before the workspace-trust dialog — even before you authenticate. Those calls are treated as “read-only, low risk”: no tool approval, no sandbox.

The bug is not in the model. It is in the pipe under it. Git has a legitimate performance knob, core.fsmonitor: on index refresh, ask an external helper what changed. That setting is read from the repository's own .git/config. A repo can ship a command there; the moment the agent touches the index, it runs on the host as you — with nothing on screen.

The git you didn't run → already ran as you

GitSpawn: not injection — the git underneath you

Manifold Security (2026-09-01) named the class GitSpawn: eight findings across seven mainstream coding agents. By disclosure day, Claude Code (core.fsmonitor), Codex, Cursor, and Goose had patched at least one path; Qwen Code, Grok Build, Hermes, and Claude Code's second variant (ultrareview) stayed live. The CSA note of 2026-09-04 nails the table: Goose carries CVE-2026-72718 (CVSS 7.0), Codex CVE-2026-19592 / 19593, Hermes CVE-2026-71963 from VulnCheck after six unanswered vendor contacts.

The chain is surgically clean: no prompt injection; the model may never see the payload. Delivery is not git clone (clone does not import the peer's local config) — it is a zip / shared drive / USB that keeps .git. Colleagues pass projects this way every day. The agent's own context gatherer spawns git; git honors the hostile fsmonitor; the command runs outside the sandbox, outside approval, as you.

A trust dialog cannot catch a click you never made

We thought the danger was the shell the model wanted to run. GitSpawn says the real danger is the few “read-only” commands the product runs before you speak, so it can look smart. Trust dialogs, tool approvals, sandboxes sit one layer up. If the pipe underneath is not sanitized, the upper layer is theater.

In the same year GhostApproval, Sonar's trust-before-click, and Cursor's git.exe zero-day keep hitting the same plank: repository-supplied metadata is trusted by default. GitSpawn nails that plank hardest — a legitimate config key, legitimate git behavior; the illegitimacy is an agent that touches git without stripping the repo's config.

One move tonight

Open the last project you received as files, not as a clone. Do not launch an agent yet. Inside the directory run:

git config --get core.fsmonitor

If it prints anything — learn who wrote it before Claude / Cursor / Codex ever touch the folder. On the vendor side: every background context gather must pass git -c core.fsmonitor=false …. Stop trusting the repo's own config.

The git you didn't run already ran as you. Check .git/config first. Then let the agent touch the repo.