A dating note first. Manifold Security disclosed GitSpawn on September 1 and 2. I didn’t cover it then. It’s in front of me now because October’s security roundups lead with it, and because some of what it found was reportedly still unpatched at publication. So this is a catch-up post, not breaking news.
What it is: eight findings across seven coding agents. Claude Code, Codex, Cursor, Goose, Hermes Agent, Qwen Code, and Grok Build. The mechanism is almost boring. Coding agents run background git commands, like git status and git diff, as soon as they open a project, to learn the branch and which files changed. Git honors a repository-local setting called core.fsmonitor that names a command to run whenever it refreshes its index. If a poisoned .git/config points that setting at an attacker’s command, the agent’s routine git status runs it. With the user’s permissions. Before any model-level permission prompt appears. Some affected agents did this before the user had typed a prompt or approved workspace trust.
The condition that matters, and that some headlines blurred: the repository has to arrive with its .git directory. A zip file, a shared drive, a USB stick. An ordinary git clone, fetch, or pull doesn’t transfer the remote’s .git/config. So “never clone anything” isn’t the lesson. The lesson is to be careful with project folders you received as plain files.
Patch status, as far as I can tell: Claude Code’s core.fsmonitor issue was confirmed in version 2.1.193 and reportedly fixed in 2.1.196. Manifold also reported a separate issue in Claude Code’s ultrareview path, using a different git config execution sink, that was unpatched at publication. Across all eight findings, Adversa’s roundup says four were unpatched when the research went out. I don’t know where each one stands today. Check your own agent’s version.
Why this class of bug keeps showing up: approvals gate what the model decides to do. They don’t gate what the harness does by itself on startup. It’s the same shape as the DeepSeek Harness CVE, where the dangerous step wasn’t something the model chose. The agent opened a folder, and the folder ran code.
Adversa’s October roundup puts the larger pattern bluntly: the month’s attacks rarely touched the model. They ran through git config, plugin pins, hooks, subagent configs, and sandbox mount paths, all things an agent reads automatically when it opens a folder. Their advice is to treat every repository as executable input.
What to do:
- Update your agents.
- For any project you received as loose files, look at
.git/configbefore opening it, or rungit config --local --get core.fsmonitorin it. It should print nothing. - If you build agent tooling, pass
-c core.fsmonitor=false -c core.hooksPath=/dev/nullon background git calls. A command-line-coverrides the repository’s own config.
One caution. Some write-ups also suggest setting core.fsmonitor to false globally. As far as I know, git lets a repository’s local config override your global one, so that alone won’t stop a poisoned .git/config. The local check and the -c flag are the ones that do the work.