The Repo Ran Code Before You Typed a Word: GitSpawn and How Hermes Fixed It


Friday afternoon, a teammate zips up a project and messages you: “take a look at this bug.” You unzip it, drag the folder into Hermes, and start typing your first instruction — but in those few seconds, code that isn’t yours has already finished running on your machine, with your permissions. No popup, no approval prompt, nothing on screen. This isn’t a movie plot: it’s a real vulnerability class disclosed by security firm Manifold Security on September 1 under the name GitSpawn, affecting nearly every mainstream AI coding tool — Claude Code, Codex, Cursor, Goose, Qwen Code, Grok Build, and Hermes Agent. The good news: Hermes merged its fix on September 2 (PR #101483, currently on main).

How it works: the repo you opened “runs” a command for you

AI coding tools — Hermes included — run a few git commands at startup to figure out where they are: which branch you’re on, which files changed. This context gathering happens automatically, before any prompt, before any tool call, before any workspace-trust confirmation. The agent has to know where it is before it can do anything.

The problem sits in a git performance feature: core.fsmonitor. On large repositories, git doesn’t want to scan every file to decide what changed, so it lets you configure a helper program to answer that question instead. Git runs that program on every index refresh — and commands like git status and git diff trigger an index refresh.

The catch: git reads this setting from the repository’s own .git/config. So a hostile repository can ship this:

[core]
    fsmonitor = /tmp/pwn.sh

Then all you have to do is open the repository — without saying a word — and the git status Hermes runs automatically makes git execute /tmp/pwn.sh. As you, with your privileges, outside the sandbox, with no approval UI. An attacker gets more than “can run code”: your SSH keys, cloud credentials, shell tokens, and a foothold on the whole machine.

core.fsmonitor is just one sink in the class. Manifold’s report also covers core.hooksPath (hooks on checkout), pager/editor/credential settings, and the sneakier .gitattributes-scoped diff drivers ([diff "x"] command= / textconv=, executed when a diff renders). The last kind is the nastiest: the attacker picks the driver name, so environment-variable overrides can’t enumerate it — only command-line flags can shut it down.

How it spreads: why git clone is safe and zip files are not

This vulnerability has a counter-intuitive property: cloning a hostile repo over the network is safe. git’s clone/fetch/pull never transfers .git/config — that’s a private file of your local repository, and the remote’s version is irrelevant to you.

What’s dangerous is a repository that arrives as directory files: with its .git folder intact. A shared zip, a synced cloud folder, a USB stick, a project directory a colleague copied directly — every one of those preserves the sender’s .git/config. Manifold’s proofs of concept used a zip.

So the rule of thumb is simple: be wary of “packaged project folders” handed to you by someone else before you open them with an AI tool; anything you git clone is inherently safe.

Industry response: eight findings, four still unpatched at disclosure

Manifold Security published the full report on September 1, covering eight findings across seven AI coding tools. Status at publication:

Tool Status
Claude Code (fsmonitor path) Fixed (2.1.196)
Claude Code (ultrareview path) Unpatched at disclosure (still vulnerable on 2.1.252)
Goose Fixed (1.44.0, CVE-2026-72718)
Codex / Cursor Fixed
Hermes Agent Unpatched at disclosure — fix merged September 2
Qwen Code / Grok Build Unpatched at disclosure

The Hacker News’ September 2 coverage still listed Hermes as “fix pending” — but Nous Research merged the fix into main that same day, a day newer than the reporting.

Hermes’s fix: turning “bare git” into “sanitized git”

The fix (PR #101483, commit f6234d00c5) is straightforward in concept: every git probe Hermes initiates itself now runs in a sanitized environment that ignores the repository’s own config entirely.

Two layers of defense:

Layer 1 — environment sanitization (noninteractive_git_env()). All automatic probes now default to a “non-interactive git environment” that pins core.fsmonitor, core.hooksPath, pager, editor, and credential helpers to inert values via GIT_CONFIG_*, and ignores global and system config. When git status refreshes the index, there is no longer any “repository-specified helper program” to run. Covered call sites include the workspace-context snapshot (coding_context), the gateway’s project-tree build, @diff/@staged context references, the goal-gate fingerprint, and -w startup worktree add.

Layer 2 — command-line flags (harden_git_argv()). Environment variables can’t reach .gitattributes-scoped drivers (the attacker names the driver, so you can’t enumerate it), so for diff-rendering subcommandsdiff, show, log, blame — Hermes now injects --no-ext-diff --no-textconv, cutting off both the [diff "x"] command= and textconv= execution points at the command-line level.

A real-git end-to-end regression suite ships with the fix: it arms a repository with malicious config and asserts every automatic path fails to execute fsmonitor, hooks, external-diff, or textconv.

What you should do now

  1. Know your version: the fix landed on September 2 and is not in any formal release yet (the latest release, v0.21.0, shipped August 31 — before the fix). If you want first-day protection, track main or wait for the next patch release; either way, start practicing the habits below.
  2. Be suspicious of “file-form” repositories: check zip files, synced folders, and USB-copied project directories before opening them. Repos you git clone need no such worry.
  3. Self-check a received project before handing it to Hermes:
cd path/to/suspicious-project
git config --get core.fsmonitor      # output here = be alert
git config --get core.hooksPath
grep -nE "command *=|textconv *=" .git/config
  1. Don’t open a session directly in a suspicious directory: if you must review the code, git clone a clean copy first and point Hermes at that.

This incident pairs with the SSH config approval gate we covered earlier as the same class of lesson: the low-level commands an AI tool runs automatically must assume their input is untrusted. Hermes’s fix pulls even the earliest, most invisible step — context gathering — inside the trust boundary. Where you can’t see it, it now assumes the repository might be the enemy.