Vers 09 h 00 UTC le 4 août, un attaquant a pris le contrôle du compte GitHub de Jared Wray. Il a utilisé cet accès pour injecter du code malveillant directement dans la branche main du dépôt keyv, puis pour publier de nouvelles versions de plusieurs paquets de l’écosystème keyv et cacheable .
La première vague concernait 11 paquets répartis entre les deux espaces de noms, dont keyv, cacheable-request, cache-manager, @cacheable/utils, flat-cache et file-entry-cache . Des équipes de recherche d’Aikido Security, StepSecurity, Socket et Chainguard ont confirmé la compromission dans les premières heures .
setup.mjs et Math_Symbol.jsChaque paquet contaminé présentait le même schéma :
setup.mjs et Math_Symbol.js ;package.json ajoutant l’entrée "preinstall": "node setup.mjs" .Dès qu’un développeur ou un serveur d’intégration continue exécutait npm install, le script setup.mjs se lançait automatiquement, avant la fin de l’installation. Ce dropper téléchargeait ensuite depuis GitHub Releases un binaire légitime du runtime JavaScript Bun, avant de l’utiliser pour lancer la seconde étape, un fichier JavaScript fortement obfusqué nommé Math_Symbol.js, d’une taille d’environ 710 à 728 Ko .
Microsoft Threat Intelligence a identifié cette charge utile comme une variante de Mini Shai-Hulud . Le malware cherchait notamment à récupérer :
L’élément le plus préoccupant n’était pas seulement le vol de secrets, mais la capacité du malware à se propager seul. Après avoir récupéré des jetons de publication npm et des PAT GitHub dans un environnement infecté, il les utilisait pour publier des versions piégées d’autres paquets, parfois détenus par des mainteneurs sans lien avec la famille keyv .
L’ampleur de la propagation a augmenté presque en temps réel :
Le ver a franchi les frontières entre espaces de noms. Il ne s’est pas limité aux projets keyv et cacheable, mais a atteint des paquets associés à des organisations telles que Deliveroo, Ornikar, OneReach, Picsart, Qlik et ServiceTitan .
Les identifiants collectés ont été exfiltrés vers un dépôt GitHub contrôlé par l’attaquant. Selon les analyses disponibles, le malware pouvait créer un dépôt dédié ou utiliser un dépôt déjà prévu pour cette collecte . La charge utile intégrait plusieurs canaux d’exfiltration redondants, de manière à rester opérationnelle même si l’un d’eux était neutralisé .
Les chercheurs recommandent de considérer tout environnement ayant exécuté npm install avec une version contaminée comme potentiellement compromis. Supprimer les fichiers malveillants ne suffit pas : les secrets présents sur la machine ont pu être lus et transmis.
Épinglez immédiatement les dépendances sur des versions reconnues comme saines ou revenez à une version antérieure à l’incident. Les mécanismes overrides de npm, Yarn ou pnpm peuvent empêcher la réinstallation accidentelle d’une version contaminée .
Vérifiez également les fichiers de verrouillage — package-lock.json, yarn.lock et pnpm-lock.yaml — en recherchant les versions compromises, y compris lorsqu’elles apparaissent comme dépendances transitives .
Ne vous contentez pas de retirer le paquet malveillant du disque. Une machine ou un runner CI/CD qui a exécuté l’installation doit être traité comme entièrement exposé . Dans la mesure du possible, reconstruisez les environnements depuis des images propres.
Révoquez puis régénérez tous les secrets susceptibles d’avoir été accessibles depuis l’environnement infecté, notamment :
Un point de vigilance est particulièrement important : le malware pouvait installer des watchers de workflows GitHub capables de surveiller la création de nouveaux jetons et de les exposer à nouveau . Les chercheurs recommandent donc de désactiver ou supprimer tout service ou workflow suspect avant de procéder à la rotation des identifiants .
Supprimez les caches npm, pnpm et Yarn sur les postes de développement et les runners CI/CD. Purgez également les caches de construction Docker, puis recréez les artefacts depuis zéro afin d’éviter qu’une dépendance contaminée ne subsiste dans une couche Docker ou un cache de build .
Recherchez les dépôts récemment créés, les workflows non autorisés, les commits inhabituels et les mécanismes de persistance. Les chercheurs ont notamment signalé des fichiers tels que .claude/settings.json et .vscode/tasks.json susceptibles d’avoir été ajoutés par le ver .
L’incident du 4 août illustre le risque systémique des registres de paquets : un seul compte de mainteneur compromis peut servir de tremplin vers des centaines de projets indépendants. La combinaison d’un script preinstall, du téléchargement d’un runtime Bun légitime, du vol de jetons et de la republication automatique de paquets a permis à l’attaque de changer d’échelle en quelques heures .
Pour les équipes de développement et de sécurité, les leçons sont concrètes : épingler les dépendances, limiter ou désactiver les scripts d’installation lorsque c’est possible, surveiller les activités GitHub inhabituelles et préparer un plan de réponse spécifique aux compromissions de la chaîne logicielle.