Why AI-Built Apps Break · For engineers

GitSpawn: how a shared repo hijacks your AI coding agent

A repository's own .git/config can make your AI coding agent's background git status run any command. We reproduced GitSpawn and tested what blocks it.

Short answer GitSpawn, disclosed by Manifold Security on September 1, 2026, lets a folder's .git/config (core.fsmonitor) run a command when an AI coding agent calls git status or git diff, before any approval prompt. Clone received folders with git clone --no-local, update your agents, and force core.fsmonitor=false through GIT_CONFIG_* variables.

Until version 2.1.196, opening a folder with Claude Code ran git status before you typed anything, before the workspace-trust promptSource 1. On September 1, Manifold Security showed what that means when the folder came from someone else: the repository decides what that git status runs. They called it GitSpawn, documented eight findings across seven agents, four still unpatched when they published, and say they found it in more agents than they nameSource 1.

The risk itself isn't new. In 2024 the Git project advised against working in repositories obtained as archives from untrusted sourcesSource 2, and recommended cloning them first with git clone --no-local. What changed is that agents made the risky step automatic: they run git on their own, some at start-up and some once the session beginsSource 1. We reproduced the core of it, tested the defenses people suggest, and found that the obvious way to inspect the config, git config --local --list, can run a planted command too.

§1

A performance setting that names a program

core.fsmonitor exists to make git fast on big repositories. Instead of scanning every file, git asks a helper what changed. The setting can hold the path of that helper commandSource 3, and any git command that refreshes the index runs it, git status and git diff includedSource 1.

Git reads that setting from the repository's own .git/config. So a repository can carry [core] fsmonitor = <any command>, and the next routine git status in that folder runs it, as you, with your privileges.

Agents call git for context all the time: the current branch, the changed files, the diff for a review. Manifold found those calls passed the repository's config through unfiltered. Because the agent's own code spawns git, the command runs outside the sandbox and without an approval promptSource 1. The permission model never sees it.

§2

What ran the planted command in our test, and what stopped it

On 2 October 2026 we built a repository in Docker (the alpine/git image, git 2.54.0) and planted a harmless command: git config core.fsmonitor 'touch /work/PWNED; false'. Then we ran what agents typically run, and the defenses people suggest. Note the first row: while the planted command ran, git status still printed "nothing to commit, working tree clean". Nothing on screen gives it away.

Did the planted command run? Our test, alpine/git (git 2.54.0) in Docker, 2 October 2026.
What ran in the received folderPlanted command ran?
git statusYes, ran
git diff --name-only HEADYes, ran
git config --local --list, in a terminal, with a planted pagerYes, ran
git status with core.fsmonitor=false in the global configYes, ran
git -c core.fsmonitor=false statusNo, blocked
git status in a copy made with git clone --no-localNo, blocked
git status with GIT_CONFIG_COUNT=1, GIT_CONFIG_KEY_0=core.fsmonitor, GIT_CONFIG_VALUE_0=falseNo, blocked
Same variables, git started by a child shell (sh -c)No, blocked

Four results matter for what you do next.

A clone drops the repository's config; a copied folder keeps it

A repository's .git/config is not part of what git transfers. Manifold makes the same point: cloning a hostile URL does nothing, and neither does fetch or pullSource 1. The folder has to arrive with its .git directory inside, through a shared .zip, a shared drive, a sync folder or a USB stickSource 1. That is how consultants receive client code and how take-home coding tests travel. We know of no GitSpawn attack yet, but the delivery route is in use: Check Point's 7 September report cites a campaign sending malware in fake LinkedIn coding testsSource 4.

Reading the config with git can run a planted command too

The obvious way to inspect a suspicious repository is git config --local --list. Don't. In a terminal, git sends that output through a pager, and the repository's config can choose the pager. In our test a planted core.pager ran the moment we listed the config. Read .git/config with cat instead.

Your global config can't override the repository

Setting core.fsmonitor=false in ~/.gitconfig does nothing here, because git reads the repository's config after the global one and the last value winsSource 3. It feels like a fix, which makes it a trap.

Environment variables do override it

Git also reads GIT_CONFIG_COUNT, GIT_CONFIG_KEY_<n> and GIT_CONFIG_VALUE_<n> from the environment, and those override every config fileSource 3. In our test a child shell inherited them and its git stayed blocked. We didn't test each agent: one that starts git with a cleaned environment would drop them.

§3

Which agents were affected, and their status on September 1

GitSpawn findings by agent, as Manifold Security reported them on 1 September 2026.Source 1
AgentStatus on 1 September 2026
Claude Code, start-up git statusFixed in 2.1.196
Claude Code, claude ultrareviewUnpatched on 2.1.252
GooseFixed in 1.44.0 (CVE-2026-72718)
Hermes AgentUnpatched on 0.21.0 (CVE-2026-71963)
Qwen CodeUnpatched on 0.22.3
Grok BuildUnpatched on 1.0.13
OpenAI Codex, CursorPatched

A month has passed, so check each vendor before you rely on this table. Changelogs don't always name GitSpawn, so compare version numbers and ask the vendor directly.

§4

What to do this week

  1. Update past the fixed versions above. Until the unpatched agents ship a fix, don't run them on code that arrived as files.
  2. Never point an agent at a folder you were sent. Clone it first with git clone --no-local received-folder clean-copy, which the Git project recommends for untrusted repositoriesSource 2. Use Git 2.45.1 or later (or 2.39.4 to 2.44.1): that same advisory fixed a way around the clone's protectionsSource 2. In our test the copy carried no fsmonitor setting.
  3. Before opening a folder you didn't create, read .git/config with cat, not with git, and list .git/hooks/. core.fsmonitor is the known case, but Manifold found a second setting of the same kindSource 1, so treat any key that names a command as hostile until you know why it's there.
  4. Add export GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=core.fsmonitor GIT_CONFIG_VALUE_0=false to ~/.zshrc or ~/.bashrc, launch your agents from that terminal, and check that git config --show-origin core.fsmonitor prints command line: false. It covers this one setting, not the others, and it also switches fsmonitor off in your own large repositories that use it for speed.
  5. Run agents on code you don't trust in a container or VM that holds no SSH keys, cloud credentials or tokens.

Workspace-trust prompts exist because opening a folder is a decision. GitSpawn happened because some agents did work before asking. Until every agent asks first, the clean clone and the environment variable act before any prompt can.

  1. Agents past the fixed versions And the unpatched ones kept away from received folders.
  2. Received folders cloned with --no-local, never opened as received
  3. .git/config read with cat, not git git config --local --list can run a planted pager.
  4. GIT_CONFIG_* override in the shell that starts the agent Not in ~/.gitconfig, where the repository wins.
  5. Untrusted code runs in a container with no credentials

Sources

  1. GitSpawn: A Single Flaw Lets Untrusted Repos Run Code in Claude Code, Codex, Cursor, and Grok (Manifold Security, Sep 1, 2026). Retrieved . ↩ ↩ ↩ ↩ ↩ ↩ ↩ ↩ ↩
  2. Protections for cloning untrusted repositories can be bypassed (Git security advisory, CVE-2024-32465). Retrieved . ↩ ↩ ↩
  3. git-config documentation (Git). Retrieved . ↩ ↩ ↩
  4. 7th September Threat Intelligence Report (Check Point Research). Retrieved . ↩

Published · Updated Report an error (support@agentum.cloud)