Le repo a exécuté du code avant que vous ne tapiez le moindre mot : GitSpawn et comment Hermes l'a corrigé


Vendredi après-midi, un collègue compresse un projet et vous écrit : « jetez un œil à ce bug ». Vous décompressez l’archive, glissez le dossier dans Hermes et commencez à taper votre première instruction — mais en l’espace de ces quelques secondes, un code qui n’est pas le vôtre a déjà fini de s’exécuter sur votre machine, avec vos permissions. Aucune popup, aucune demande d’approbation, rien à l’écran. Ce n’est pas l’intrigue d’un film : c’est une classe de vulnérabilités bien réelle, divulguée le 1er septembre par la société de sécurité Manifold Security sous le nom de GitSpawn, qui touche presque tous les outils de codage IA grand public — Claude Code, Codex, Cursor, Goose, Qwen Code, Grok Build et Hermes Agent. La bonne nouvelle : Hermes a fusionné son correctif le 2 septembre (PR #101483, actuellement sur main).

Comment ça marche : le repo que vous ouvrez « exécute » une commande à votre place

Les outils de codage IA — Hermes compris — exécutent quelques commandes git au démarrage pour s’orienter : savoir sur quelle branche vous êtes, quels fichiers ont changé. Cette collecte de contexte a lieu automatiquement, avant tout prompt, avant tout appel d’outil, avant toute confirmation de trust gate du workspace. L’agent doit savoir où il se trouve avant de pouvoir agir.

Le problème se niche dans une fonctionnalité de performance de git : core.fsmonitor. Sur les gros repos, git ne tient pas à scanner chaque fichier pour décider ce qui a changé ; il vous laisse donc configurer un programme auxiliaire chargé de répondre à cette question à sa place. Git exécute ce programme à chaque index refresh — et des commandes comme git status et git diff déclenchent justement un index refresh.

Le piège : git lit ce réglage dans le .git/config du repo lui-même. Un repo hostile peut donc embarquer ceci :

[core]
    fsmonitor = /tmp/pwn.sh

Il vous suffit alors d’ouvrir le repo — sans dire un mot — et le git status que Hermes lance automatiquement pousse git à exécuter /tmp/pwn.sh. En votre nom, avec vos privilèges, hors de la sandbox, sans aucune interface d’approbation. L’attaquant n’obtient pas seulement « la possibilité d’exécuter du code » : il repart avec vos clés SSH, vos identifiants cloud, vos jetons de shell et un point d’appui sur toute la machine.

core.fsmonitor n’est qu’un point d’exécution parmi d’autres dans cette classe. Le rapport de Manifold couvre aussi core.hooksPath (les hooks au checkout), les réglages pager/editor/credential, et les diff drivers plus retors définis via .gitattributes ([diff "x"] command= / textconv=, exécutés au moment du rendu d’un diff). Cette dernière variante est la plus vicieuse : l’attaquant choisit lui-même le nom du driver, si bien qu’aucune variable d’environnement ne peut l’énumérer — seuls des flags passés en ligne de commande peuvent la neutraliser.

Comment ça se propage : pourquoi le git clone est sûr et les zip ne le sont pas

Cette vulnérabilité a une propriété contre-intuitive : cloner un repo hostile par le réseau est sûr. Les opérations clone/fetch/pull de git ne transfèrent jamais .git/config — c’est un fichier privé de votre dépôt local, et la version du distant ne vous concerne pas.

Ce qui est dangereux, c’est un repo qui arrive sous forme de fichiers : avec son dossier .git intact. Un zip partagé, un dossier cloud synchronisé, une clé USB, un répertoire de projet copié tel quel par un collègue — chacun de ces vecteurs préserve le .git/config de l’expéditeur. Les preuves de concept de Manifold utilisaient un zip.

La règle empirique est donc simple : méfiez-vous des « dossiers de projet empaquetés » qu’on vous remet avant de les ouvrir avec un outil IA ; tout ce que vous récupérez par git clone est intrinsèquement sûr.

Réaction de l’industrie : huit constats, quatre encore non corrigés à la divulgation

Manifold Security a publié le rapport complet le 1er septembre, couvrant huit constats sur sept outils de codage IA. État des lieux au moment de la publication :

Outil Statut
Claude Code (voie fsmonitor) Corrigé (2.1.196)
Claude Code (voie ultrareview) Non corrigé à la divulgation (toujours vulnérable en 2.1.252)
Goose Corrigé (1.44.0, CVE-2026-72718)
Codex / Cursor Corrigé
Hermes Agent Non corrigé à la divulgation — correctif fusionné le 2 septembre
Qwen Code / Grok Build Non corrigé à la divulgation

Dans sa couverture du 2 septembre, The Hacker News listait encore Hermes comme « correctif en attente » — mais Nous Research a fusionné le correctif dans main le jour même, soit un correctif plus récent que ce que laissait entendre l’article.

Le correctif de Hermes : transformer le « git brut » en « git assaini »

Le correctif (PR #101483, commit f6234d00c5) est simple dans son principe : chaque sonde git que Hermes lance de lui-même s’exécute désormais dans un environnement assaini qui ignore entièrement la configuration du repo.

Deux couches de défense :

Couche 1 — assainissement de l’environnement (noninteractive_git_env()). Toutes les sondes automatiques utilisent désormais par défaut un « environnement git non interactif » qui fige core.fsmonitor, core.hooksPath, pager, editor et les credential helpers à des valeurs inertes via GIT_CONFIG_*, et qui ignore les configs globale et système. Quand git status rafraîchit l’index, il n’y a plus aucun « programme auxiliaire spécifié par le repo » à exécuter. Les points d’appel couverts incluent l’instantané de contexte du workspace (coding_context), la construction de l’arborescence du projet par la gateway, les références de contexte @diff/@staged, l’empreinte de la goal gate et l’ajout du worktree au démarrage avec -w.

Couche 2 — flags de ligne de commande (harden_git_argv()). Les variables d’environnement ne peuvent pas atteindre les drivers définis via .gitattributes (l’attaquant nomme le driver, impossible de l’énumérer), aussi pour les sous-commandes de rendu de diffdiff, show, log, blame — Hermes injecte désormais --no-ext-diff --no-textconv, coupant ainsi les points d’exécution [diff "x"] command= et textconv= au niveau de la ligne de commande.

Une suite de tests de régression de bout en bout sur un vrai git accompagne le correctif : elle arme un repo d’une configuration malveillante et vérifie qu’aucun chemin automatique n’exécute fsmonitor, hooks, external-diff ou textconv.

Ce que vous devriez faire maintenant

  1. Vérifiez votre version : le correctif est arrivé le 2 septembre et ne figure encore dans aucune release officielle (la dernière, v0.21.0, est sortie le 31 août — avant le correctif). Si vous voulez une protection dès le premier jour, suivez main ou attendez la prochaine release de correctifs ; dans les deux cas, commencez dès maintenant à adopter les habitudes ci-dessous.
  2. Méfiez-vous des repos « au format fichier » : examinez les zip, les dossiers synchronisés et les répertoires de projet copiés par USB avant de les ouvrir. Les repos que vous récupérez par git clone ne demandent aucune de ces précautions.
  3. Auto-vérifiez un projet reçu avant de le confier à 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. N’ouvrez pas de session directement dans un répertoire suspect : si vous devez examiner le code, faites d’abord un git clone d’une copie propre et pointez Hermes dessus.

Cet incident s’inscrit dans la même classe de leçon que la passerelle d’approbation de config SSH que nous avions couverte précédemment : les commandes de bas niveau qu’un outil IA exécute automatiquement doivent présumer que leur entrée n’est pas fiable. Le correctif de Hermes fait entrer même l’étape la plus précoce et la plus invisible — la collecte de contexte — dans le périmètre de confiance. Là où vous ne pouvez pas voir ce qui se passe, il suppose désormais que le repo pourrait bien être l’ennemi.