← Back to posts

11 min read

GitSpawn: The Git Performance Flag That Turns Coding Agents Into Command Runners

Filed under Supply Chain

The exploit is a Git performance setting. One line in a repository's own .git/config names a command, Git runs that command during a routine status check, and your AI coding agent is what triggers the status check. Manifold Security's GitSpawn disclosure put hard numbers on the pattern: eight flaws across seven command-line AI coding agents, with four paths still unpatched at publication.

Most coverage of agent security this year has been about prompt injection or MCP misconfiguration. This is neither. The payload never touches the model. It sits in Git metadata, executes as your user, runs outside the agent's sandbox, and never passes an approval prompt.

What Manifold actually disclosed

Manifold published the findings under the name GitSpawn, wrote up five of the eight flaws in detail, and said it found the pattern in more agents than it named. Five of its eight reports came back as duplicates of findings other researchers had filed independently, one of them filed the same day. That collision rate matters. When multiple teams trip over the same sink inside a few months, the sink is obvious to anyone who looks, including people who do not report.

OpenAI underlined the point by publishing three CVEs of its own the same day, covering the identical flaw class in Codex and credited to three unrelated research groups. CVE-2026-19592 is the one identifier named so far.

This is also not the classic Git hooks story. Hooks live in .git/hooks and fire on specific lifecycle events. GitSpawn abuses a configuration key that Git reads on ordinary index operations, which is a quieter and more reliable trigger.

The clone-to-execution chain

The GitSpawn clone-to-execution chain

The sink: core.fsmonitor is a command, not a toggle

core.fsmonitor is a legitimate Git performance setting. Its value is a command Git runs to identify changed files, so large repositories do not pay for a full filesystem scan. Git reads the key from the repository's own .git/config, and any operation that refreshes the index executes it. That includes git status and git diff, the two most boring commands in the tool.

A poisoned repo needs exactly one line:

ini
[core]
    fsmonitor = <attacker command>

The trigger: your agent's first background chores

CLI coding agents do not sit idle when you open a project. To build context, they call git status or git diff in the background at session startup, learning the current branch and which files changed. They leave the repository's configuration untouched while doing it. That is the whole attack: repository config in, background Git call out, command executed.

The timing is what makes it ugly. Per Manifold's testing:

  • Claude Code and Hermes Agent fire the payload before the workspace-trust prompt is accepted. The dialog meant to protect you renders after you are already compromised.
  • Qwen Code fires it before the user has authenticated. You do not even need a working session.
  • Grok Build fires it on the first keystroke.

In every case the command runs as the user, outside the agent's sandbox, with no approval prompt.

The delivery problem: clones are clean, folders are not

Here is the constraint that keeps this from being catastrophic, and the one skeptics lean on. An ordinary git clone does not preserve local config, so cloning a malicious repo from GitHub does not carry the key. Exploitation requires the repository to arrive as files with its .git directory intact: a shared archive, a shared drive, a sync folder, a USB stick.

The pushback writes itself: who opens repos as files? Plenty of people, in my experience. Contractors hand off zips. Vendors share drives. Support teams receive repro cases as archives. Sync clients mirror project folders across machines by default. Nobody reviews .git/config before opening a folder, because until now there was no reason to. If your workflow includes "the repo arrived as a download," you are in the threat model.

Per-agent status at publication

AgentTrigger momentStatusDetail
goosegoose review Git callsFixedCVE-2026-72718, CVSS 4.0 base 7.0, the only scored finding; advisory credits Francisco Rosales
Claude Code, core.fsmonitor pathBefore workspace-trust promptFixed in 2.1.196 (June 29)Report filed June 26, closed as a duplicate of one filed earlier that day; no Anthropic advisory published
Claude Code, second pathVia claude ultrareviewUnpatchedTurns on a different config key Manifold withheld; confirmed live on 2.1.252 on September 1 against then-current 2.1.258; unknown whether later releases closed it
CursorStartup Git callsFixedFix shipped
CodexStartup Git callsFixedCovered by OpenAI's same-day CVEs
Hermes AgentBefore workspace-trust promptUnpatchedManifold says six contact attempts across five channels went nowhere and the private advisory sat untriaged; VulnCheck assigned CVE-2026-71963 per Manifold, though no public record for the identifier existed when the story broke
Qwen CodeBefore authenticationUnpatchedAlibaba's security response centre accepted the report July 7; 0.22.3, the version Manifold retested, was still the latest npm release on September 2
Grok BuildFirst keystrokeUnpatchedStill executing repository-supplied commands on retest

Two details deserve emphasis. The goose flaw is instructive for tool makers: goose review built its Git invocations with a single configuration flag, -c core.quotePath=off, and stripped nothing else. Passing one override while honoring everything else in local config is not sanitization, and GitHub's advisory title says the quiet part plainly: "Arbitrary command execution in goose CLI via goose review via git core.fsmonitor."

Second, the unpatched Claude Code path lives behind claude ultrareview and uses a different, withheld config key. Unsetting core.fsmonitor alone does not close your exposure if that binary is in your workflow.

This exact bypass has been fixed before, then unfixed

The trust-gate fix that came back

The trust-dialog bypass pattern has a paper trail. Sonar reported the same sink in April and noted that Anthropic had already moved its startup sequence once to close it. The pattern itself goes back further: Visual Studio Code before 1.63.1 (CVE-2021-43891) and JetBrains IDEs before 2021.3.1 (CVE-2022-24346) both shipped variants of "code runs before the trust prompt means anything."

Claude Code 2.0.34 shipped November 5, 2025 with a mitigation that stopped running git status before trust approval. Manifold found the same startup behavior present again in 2.1.193, which shipped June 25, 2026. A regression. Anthropic's June advisory, CVE-2026-55607, identifies fsmonitor execution during worktree operations, yet The Hacker News confirmed on September 2 that the vendor's published advisory record for the npm package covers neither Claude Code GitSpawn finding.

My read: point fixes on startup ordering will not hold. Unless the trust gate is enforced around every Git invocation, permanently and with a regression test, this comes back.

Containing it: what to do this week

If you receive repositories as files

Make one rule: any directory that arrives with its .git folder from outside your org gets inspected before an agent touches it, or it does not get opened at all.

bash
# Inspect local config for command-valued keys
git -C /path/to/repo config --local --list --show-origin

# Check and remove the known key
git -C /path/to/repo config --local core.fsmonitor
git -C /path/to/repo config --local --unset core.fsmonitor

Remember the withheld second key in the ultrareview path: unsetting fsmonitor is necessary, not sufficient. The cleaner move is to re-clone from the canonical remote and work in the fresh clone, since an ordinary clone does not carry local config. Also give .git/hooks a glance while you are in there. Hooks are a separate, older class, but the same "arrived as files" delivery exposes you to them.

Isolate the agent, because the agent cannot isolate you

The payload runs as your user, outside the agent's own sandbox, so permission modes and in-agent guardrails are the wrong layer. Put the boundary at the OS: run agents against untrusted material in a disposable container or VM, or under a separate OS account that has no access to your keys, browser profile, or cloud credentials. The playbook in Check the Socket, Not the Installer: An Audit and Lockdown Playbook for the NemoClaw Ollama Flaw transfers well to hardening any local AI tool this way.

The stakes are not hypothetical. An operator ran Hermes Agent unattended in an intrusion against a Thai government network in July. That incident was not GitSpawn exploitation, but it shows agents already run with real access and minimal supervision, which is exactly the blast radius a pre-auth, pre-trust command execution wants. We have seen the same visibility gap on the dependency side, where an agent installed 23 packages in a minute and the SBOM saw zero. And if you assume the agent's tool wrapper will catch bad behavior, our own testing says otherwise: the tool wrapper chose what leaked.

If you build one of these tools

Sanitize repository configuration before any background Git call, or do not make Git calls until trust is established. Override config explicitly at invocation rather than passing cosmetic flags. Gate worktree operations too, not just status. Then write the regression test, because the history above says the fix will silently revert otherwise.

Do not conflate this with MCP auto-execution

A separate research thread covers MCP auto-execution flaws: Claude Code (CVE-2025-59536, CVSS 8.7, plus a later lower-severity issue) and Amazon Q Developer (CVE-2026-12957, CVSS 8.5, plus a second CVE) executing repository-embedded MCP configurations at project open, before trust verification. The CSA research note covers that class. The shape rhymes with GitSpawn (repo-embedded config executes before trust), but the sink is MCP server startup, not Git index refresh, and the mitigations differ. Prompt-driven hijacks like the zero-click email chain are a third class entirely. GitSpawn deserves its own playbook because the trigger is a Git primitive your tools invoke constantly.

Vendor point fixes and annual assessments will not cover the repos your team receives between tests. If the gap here is coverage between annual tests, Axeploit's pentest workflow is the product page that matches this article.

Key takeaways

  • core.fsmonitor is a command Git executes on any index refresh, and seven coding agents trigger it via background git status or git diff calls at startup, before trust prompts, before authentication, or on the first keystroke.
  • The payload runs as your user, outside the agent's sandbox, with no approval prompt. In-agent permission modes do not contain it; OS-level isolation does.
  • Ordinary clones are safe. The attack needs the repo delivered as files with .git intact, so inspect .git/config on anything you receive that way, or re-clone and work from the fresh copy.
  • Four paths were unpatched at publication: Hermes Agent, Qwen Code, Grok Build, and Claude Code's claude ultrareview path, which uses a different config key than fsmonitor.
  • Anthropic fixed this once and regressed. Treat trust prompts as advisory, and hold tool makers to config sanitization plus regression tests.
Get started

Integrate Axeploit into your workflow today