6 min de lecture
~7 minutes
Air Security a montré que Claude Code, Codex, GitHub Copilot et Gemini CLI installent un plugin « épinglé » sur un commit approuvé sans jamais vérifier qu’ils ont bien récupéré ce commit. Il suffit d’une branche nommée comme le hash. L’agent installe le code de l’attaquant et annonce avoir respecté le pin.
Un pin qui ne vérifie pas est un post-it
Épingler une dépendance sur un hash de commit fait partie des bons réflexes de la supply chain. On relit un état précis du code, on note son SHA, et on exige que rien d’autre ne s’installe. Les marketplaces de plugins pour agents de code font la même chose : un plugin est relu, puis verrouillé sur un commit.
Air Security a trouvé en mai que quatre agents ne tenaient pas cette promesse. Claude Code, OpenAI Codex, GitHub Copilot et Gemini CLI demandaient à Git de récupérer le commit épinglé, puis installaient ce qui sortait du checkout, sans comparer le résultat au hash attendu. Le rapport est public depuis la mi-septembre, et le nom qu’il a reçu dit l’essentiel : Plugin4Shell.
Avant les détails, un point : aucun mécanisme cryptographique n’est cassé. L’attaque exploite une absence de vérification, et celle-là ne se durcit pas par configuration.
Note du PandaRedacteur : un SHA épinglé, c’est un ticket de vestiaire. Personne n’a jamais vérifié que le manteau rendu était le sien, mais le ticket était parfaitement conforme.
Le tour de passe-passe, étape par étape
Le mécanisme tient en une ambiguïté de Git : une chaîne de quarante caractères hexadécimaux peut désigner un objet commit ou le nom d’une branche. Quand les deux coexistent, Git peut préférer le nom de référence à l’objet.
- Une marketplace verrouille un plugin sur un commit précis, identifié par son SHA.
- Le propriétaire du dépôt du plugin crée une branche dont le nom est ce même SHA, et la pointe vers un code différent. Il peut la définir comme branche par défaut.
- L’agent lance le checkout du SHA épinglé. Git résout le nom de branche, et récupère le code de la branche.
- L’agent n’effectue aucune vérification après coup, et rapporte l’installation de la version verrouillée.
- Le plugin s’exécute avec les droits du développeur : fichiers, clés d’API, accès CI/CD, systèmes internes, environnements cloud.
Gemini CLI a sa variante. L’agent récupère le commit puis bascule sur FETCH_HEAD ; une branche nommée FETCH_HEAD redirige alors le checkout vers un contenu choisi par l’attaquant.
flowchart LR
A["Marketplace : plugin épinglé sur SHA"] --> B["Agent : git checkout SHA"]
B --> C{"Une branche porte<br/>le nom du SHA ?"}
C -->|"non"| D["Commit approuvé installé"]
C -->|"oui"| E["Code de l'attaquant installé"]
E --> F["L'agent annonce : version verrouillée OK"]
Une précision qui compte pour le risque réel : GitHub bloque les noms de branches et de tags qui ressemblent à des hashes. Les marketplaces hébergées sur GitHub sont donc protégées par la plateforme, pas par l’agent. Bitbucket et les serveurs Git auto-hébergés peuvent rester exploitables, selon les chercheurs. Dans un grand groupe, ce sont souvent les forges où vivent les plugins internes, justement ceux qu’on a relus.
Où en sont les éditeurs
| Agent | Statut à la divulgation |
|---|---|
| Claude Code | Corrigé en 2.1.179 |
| Codex (OpenAI) | Corrigé en 0.146.0 ; OpenAI décrit le bug dans sa PR publique : Git peut interpréter un SHA demandé comme un nom de branche |
| GitHub Copilot | Pas de correctif, malgré une notification en juin |
| Gemini CLI | Produit déprécié, pas de correctif prévu ; Google oriente vers Antigravity, où cette attaque ne s'applique pas |
Aucun CVE n’était assigné à la date de la divulgation, et aucune exploitation dans la nature n’a été rapportée. Air Security résume l’enjeu en une phrase, et je la trouve exacte : chaque agent vérifie le verrouillage sur la machine de l’utilisateur, pas dans la marketplace, donc aucune marketplace ne peut corriger ça ; le correctif doit se faire dans l’agent.
Analyse STRIDE
| Catégorie STRIDE | Applicable | Explication |
|---|---|---|
| Spoofing | Oui | Une branche prend le nom du commit relu et se fait passer pour lui. Le dépôt se déguise en version approuvée. |
| Tampering | Oui | Le code installé n'est pas celui qui a été relu ; la garantie d'intégrité du pin est annulée. |
| Repudiation | Oui | L'agent déclare avoir installé le SHA épinglé. Un audit qui se fie à ce message conclut à tort que tout est conforme. |
| Information disclosure | Oui | Le plugin lit tout ce que lit le développeur : clés, jetons CI/CD, accès cloud. |
| Denial of Service | Non | Aucun vecteur de déni de service dans cette faille ; l'objectif de l'attaquant est l'exécution de code, pas l'indisponibilité. |
| Elevation of privilege | Oui | Du propriétaire d'un dépôt de plugin à l'exécution de code avec les droits d'un développeur, sans clic supplémentaire selon les chercheurs. |
Impact potentiel
| Dimension | Niveau | Conséquence concrète |
|---|---|---|
| Confidentialité | Critique | Clés d'API, jetons CI/CD et accès cloud du compte développeur, exposés dès l'exécution du plugin. |
| Intégrité | Critique | Commits, configuration de l'agent et fichiers du poste modifiables avec les droits de l'utilisateur. |
| Disponibilité | Modéré | Pas l'objectif de l'attaque, mais un code exécuté avec ces droits peut aussi détruire. |
| Réputation | Élevé | Le pin figurait dans les preuves de conformité. Découvrir qu'il ne vérifiait rien est difficile à expliquer à un client ou à un auditeur. |
Mitigations
- Mettre à jour as usual. Pour Copilot, aucune version corrigée n’existe à la divulgation : la mitigation passe par les points suivants. Pour Gemini CLI, migrez.
- Réduire les sources. Installez des plugins depuis les marketplaces GitHub intégrées, où la plateforme bloque les noms de branches qui imitent un hash, et désactivez la mise à jour automatique des plugins issus de dépôts tiers.
- Inventorier les plugins de chaque poste et de chaque agent, avec leur origine et leur SHA. Un plugin que l’on ne sait pas lister ne se vérifie pas.
- Surveiller les dépôts de plugins : création de branches, changement de branche par défaut, transfert de propriété.
- Préférer des artefacts signés à des références Git quand c’est possible : une signature se vérifie, un nom de branche se détourne (Cosign en est le point de départ).
- Vérifier après coup. La correction attendue des éditeurs tient en une comparaison, et rien n’empêche une équipe de la faire dans son propre outillage d’installation :
La famille de défauts
Plugin4Shell ressemble à ce que racontait GitSpawn : une configuration ou une référence Git suffisent à faire exécuter du code à un agent, avant que le moindre contrôle humain intervienne. Et le volet 1 des AI-Pods range cette catégorie dans les multiplicateurs qui se cumulent : privilèges, opacité et monoculture. Quatre éditeurs, la même absence de vérification : un défaut de famille, pas un incident isolé. DeepSeek Harness montrait quelques jours plus tôt le même genre d’erreur d’un autre côté : un contrôle qui croit une déclaration au lieu de vérifier un fait.
Note du PandaRedacteur : « on a épinglé, on est tranquilles » est la phrase qui ouvre le plus d’incidents de supply chain. La suite commence généralement par : « et personne ne vérifiait que le pin tenait ».
📚 Quelques références pour aller plus loin
- The Hacker News : Plugin4Shell Lets Repository Owners Swap Pinned Plugin Code Across Four AI Coding Agents
- Cyber Security News : Plugin4Shell Zero-Click RCE Hits Claude Code, Codex, Copilot and Gemini CLI
- GBHackers : Plugin4Shell Zero-Click RCE Hits Claude Code, Codex, Copilot and Gemini CLI
- GitSpawn : une clé Git qui exécute du code avant le dialogue de confiance
- DeepSeek Harness : l’agent sandboxé qui éteint lui-même son bac à sable
- AI-Pods : l’équipe de développement rétrécit, la surface d’attaque grandit

