Catégories

Tags

🔍 Licence d'Utilisation 🔍

Sauf mention contraire, le contenu de ce blog est sous licence CC BY-NC-ND 4.0.

© 2025 à 2042 Sébastien Gioria. Tous droits réservés.

⏱️
Temps de lecture estimé
4 min de lecture

Le 4 août 2026, le compte GitHub du mainteneur de keyv est compromis. En moins de quatre heures, 440 packages npm sont backdoorés ; le compteur finira au-delà de 800, soit environ deux milliards d’installations mensuelles. Un ver, baptisé CHAINDROP, se republie tout seul, siphonne les credentials cloud, CI et IA, et plante des hooks dans .claude/settings.json.

Le détail qui devrait vous empêcher de dormir : les versions vérolées portent une provenance npm parfaitement valide, signée par GitHub Actions.


Troisième round, mêmes signatures

J’ai consacré une série entière à ce ver en janvier, de la présentation au threat model en passant par les bonnes pratiques de protection des pipelines. Je pensais écrire un post-mortem. J’écris une suite (avant la prochaine suite…sans fin ? ).

Le 4 août, Elastic Security Labs repère 546 dépôts GitHub publics créés dans la journée, tous avec la même description : “Shai-Hulud: Here We Go Again”. Les attaquants signent leur travail.

Le point d’entrée : le compte GitHub du mainteneur derrière keyv. Un seul humain, mais un humain qui a les droits de publication sur tout un pan de l’écosystème caching de npm : flat-cache (~580 M d’installations mensuelles), file-entry-cache (~571 M), cacheable-request, cache-manager. Aucun de ces noms n’apparaît dans votre package.json. Ils apparaissent tous dans votre package-lock.json, trois à cinq niveaux plus bas.

Note du PandaRedacteur : on continue collectivement à sécuriser les dix dépendances qu’on a écrites à la main dans le package.json, pendant que les 1 400 autres arrivent par la porte de service. Le lock file, c’est la liste des invités que personne ne relit.

Le composant de collecte balaie plus de 300 patterns sur la machine. Ce qui est nouveau par rapport aux vagues précédentes : les credentials d’outillage IA (Anthropic, Claude, Codex, Cursor, OpenAI, Gemini) sont ciblés au même rang que les clés AWS, les service accounts Kubernetes et les tokens Vault.


Le vrai sujet : la provenance a fonctionné, et n’a rien empêché

C’est le passage que la plupart des relais de cette actu ont raté.

Depuis deux ans, on vend la provenance npm et SLSA (et moi le premier :)) comme la réponse aux attaques de supply chain. Le ver n’a pas contourné la provenance. Il est passé par elle : commit malveillant dans le dépôt légitime, sur la branche légitime, et le workflow de publication légitime a fait exactement son travail : construire, signer, publier.

La provenance atteste la chaîne de build. Elle n’atteste ni l’intention du commit, ni l’identité réelle de celui qui l’a poussé.

npm audit signatures est content. Sigstore est content. Le SLSA niveau 3 est atteint et respecté de bout en bout. Et vous avez quand même un infostealer sur votre runner.


La persistance dans vos agents

Les deux vagues précédentes s’arrêtaient à npm et GitHub. Celle-ci ajoute deux vecteurs que je n’avais jamais évoqué dans un ver de supply chain (normal, c’est un element qui est MAINTENANT mandatory dans tout dev l’IA…): un hook SessionStart dans .claude/settings.json, et une tâche folderOpen dans .vscode/tasks.json.

Traduction : même après avoir purgé node_modules et réinstallé proprement, le code de l’attaquant se relance à l’ouverture du dossier dans votre éditeur. Et quand le ver trouve un token GitHub App valide, il commite ces hooks sur jusqu’à 50 branches, signés claude@users.noreply.github.com, message chore: update config.

Note du PandaRedacteur : on a passé des mois à s’inquiéter que les agents de code écrivent du code vulnérable. Pendant ce temps, les attaquants ont compris que le vrai cadeau, c’était que les agents de code écrivent des commits que plus personne ne relit.


Ce que contient la version complète

Voici l’essentiel du mécanisme et le point sur la provenance. L’analyse complète part d’abord aux abonnés payants de ma newsletter :

  • l’analyse STRIDE détaillée des six catégories, avec le cas particulier de la répudiation via les commits attribués à l’agent ;
  • le tableau d’impact potentiel (confidentialité, intégrité, disponibilité, réputation) ;
  • la liste complète des indicateurs de compromission (fichiers, processus, domaines, patterns de commits, configurations d’agents) et un script Python de balayage local ;
  • le plan de remédiation ordonné : quels tokens révoquer, dans quel ordre, quelles clés IA faire tourner, comment purger la persistance dans les 50 dernières branches ;
  • pourquoi la période de latence de 72 heures est le contrôle le moins coûteux et le plus efficace du lot.
📬 Analyse complète réservée aux abonnés payants
L'analyse détaillée (STRIDE complet, IoC, script de détection, plan de remédiation) part d'abord aux abonnés payants de ma newsletter Substack, avant d'être publiée intégralement ici. Pour la lire en avant-première, c'est sur sgioria.substack.com.

📚 Références


À retenir 📌

  • Un compte de mainteneur compromis le 4 août 2026 a suffi à backdoorer 440 packages npm en moins de quatre heures, plus de 800 au total, pour environ deux milliards d'installations mensuelles.
  • La provenance npm signée par GitHub Actions était valide sur les versions vérolées : elle atteste la chaîne de build, jamais l'intention du commit ni le contrôle réel du compte source.
  • Le ver cible explicitement les credentials d'outillage IA (Anthropic, OpenAI, Gemini, Cursor, Codex) au même rang que les clés AWS et les tokens Kubernetes.
  • La persistance passe par .claude/settings.json et .vscode/tasks.json : elle survit à la purge de node_modules et se relance à l'ouverture du projet dans l'éditeur.
  • Une période de latence de 72 heures avant adoption d'une nouvelle version aurait suffi, seule, à ne jamais installer cette vague.