Cybersécurité

Mini Shai-Hulud : quand npm découvre encore que la supply chain n’est pas un détail

Cyril Pineiro · 10 min de lecture

Date : 15/05/2026

Illustration Pentest et Red Teaming des systèmes d’IA
Mini Shai-Hulud : le ver npm qui a transformé le pipeline CI/CD en distributeur officiel de malware

La dernière campagne Mini Shai-Hulud nous rappelle une vérité simple mais encore visiblement difficile à avaler : une chaîne de build n’est pas automatiquement fiable sous prétexte qu’elle tourne dans GitHub Actions, qu’elle parle OIDC et qu’elle produit une attestation de provenance joliment signée.

Cette fois, l’incident a touché l’écosystème npm autour de paquets largement utilisés, notamment TanStack, puis d’autres paquets liés à Mistral AI, UiPath, Squawk et plusieurs mainteneurs. Le tout dans un but très classique : voler des secrets développeurs et CI/CD, puis se propager. Bref, la supply chain logicielle dans son état le plus moderne : automatisée, signée, rapide, parfaitement capable de distribuer une compromission à grande échelle avec le sourire.

Le vrai sujet n’est pas seulement :

“un package npm a-t-il été compromis ?”

Mais plutôt :

“que peut faire un attaquant quand le pipeline légitime devient son canal de distribution ?”

Ce qui s’est passé

Le 11 mai 2026, plusieurs versions malveillantes des packages @tanstack/* ont été publiées sur npm en l'espace de quelques minutes. Selon le post-mortem TanStack, l’attaque a combiné trois éléments : le pattern pull_request_target dangereux, un empoisonnement de cache GitHub Actions à la frontière de confiance fork/base, puis l’extraction en mémoire d’un token OIDC depuis le runner GitHub Actions.

Ce qui est important, c’est la nuance : l’attaquant n’a pas seulement volé le mot de passe d’un mainteneur fatigué un vendredi soir. Il a abusé de la mécanique de publication elle-même. Le workflow légitime a publié des artefacts malveillants. C’est plus chic, plus fourbe, et infiniment plus délicat à exposer devant un comité de crise.

Snyk rapporte que 84 artefacts malveillants ont été publiés sur 42 packages TanStack entre 19h20 et 19h26 UTC. Aikido a quant à lui détecté 373 entrées de versions malveillantes sur 169 noms de packages npm. BleepingComputer rapporte que la campagne a également abusé de tokens OpenID Connect valides pour publier des variantes malveillantes avec attestation de provenance vérifiable.

La provenance prouve que le colis vient du bon entrepôt.

Elle ne prouve pas que personne n’a remplacé le contenu pendant la préparation.

Pourquoi cette attaque est intéressante

Ce n’est pas un simple typosquatting du style expres-js installé par hasard entre deux cafés. L’attaque pointe directement les mécanismes de confiance utilisés par les équipes modernes : CI/CD, publication automatisée, OIDC, attestations, cache de build et permissions de runner.

En d'autres termes, l’attaquant ne se contente pas de faire télécharger un mauvais package. Il essaie de faire produire un mauvais package par un système qui ressemble à un système légitime, avec les bons tampons, les bons workflows et la bonne odeur rassurante du “tout est vert dans le pipeline”.

C’est exactement ce qui rend ce type d’incident dangereux pour les équipes cyberdéfense. Une partie des contrôles traditionnels vise à vérifier l’origine. Mais si l’origine est compromise au moment ou on produit l’artefact, l’artefact malveillant peut arriver avec une chaîne de confiance qui parait propre.

Un artefact signé n’est pas automatiquement sain.

Il est seulement signé.

Le rôle du pipeline CI/CD

Dans de nombreuses organisations, le pipeline CI/CD est devenu un lieu de privilèges concentrés. Il peut lire des secrets, builder, tester, signer, publier, pousser une image Docker, déclencher un déploiement Kubernetes, appeler un cloud provider et notifier Slack avec un emoji fusée pour nous faire croire que "tout va bien".

Le problème est pourtant clair, si un attaquant est en mesure d’influencer ce pipeline, il n’a plus besoin de compromettre la production en direct, puisqu’il peut compromettre l’usine qui fabrique les artefacts consommés par les autres.

Dans le cas Mini Shai-Hulud, l’intérêt opérationnel est clair : voler les identités et secrets disponibles dans les environnements développeurs et runners CI/CD, puis élargir la compromission. GitHub tokens, npm credentials, clés cloud, secrets de CI, clés SSH, configurations locales : tout ce que l’industrie a patiemment accumulé dans des variables d’environnement ou vault en espérant que personne ne regarderait trop fort.

La fausse tranquillité des attestations

Les mécanismes de provenance, les signatures, OIDC et SLSA restent utiles. Il ne faut pas jeter ces contrôles parce qu’un attaquant les a contournés ou abusés. Mais il faut arrêter de leur demander ce qu’ils ne peuvent pas garantir.

Une attestation peut répondre à des questions importantes :

  • Quel workflow a produit l’artefact ?
  • Quelle identité a publié le package ?
  • Quelle chaîne de build a été utilisée ?
  • La publication correspond-elle à une provenance attendue ?

Mais elle ne répond pas toujours à la question qui compte le plus pendant une attaque :

Le runner était-il sain au moment exact où il a produit et publié l’artefact ?

Et c’est là que le sarcasme devient presque une mesure de défense : nous avons passé des années à rendre la supply chain plus vérifiable, puis nous avons parfois oublié de traiter les runners comme des systèmes hautement sensibles.

Ce que les défenseurs doivent regarder

Pour une équipe cyberdéfense, il n’y a pas de “patch” à appliquer. Il faut assurément mettre à jour les dépendances, mais cela ne suffira pas. On parle ici de l’impact de la compromission sur l’environnement qui a installé, rebuildé ou exécuté les packages affectés.

1. Identifier l’exposition

  • Auditer les package-lock.json, pnpm-lock.yaml et yarn.lock.
  • Rechercher les versions publiées dans la fenêtre d’attaque.
  • Contrôler les caches npm, pnpm, Yarn et les caches CI.
  • Vérifier les images Docker buildées pendant la période.
  • Identifier les runners ayant installé ou testé les versions compromises.

2. Traiter les secrets comme potentiellement exposés

Si un environnement a permis l’exécution d’une version malveillante, il faut partir du principe que l’on est compromis. Pas par plaisir, mais parce qu'il faut être réaliste plutôt que de rester dans l’attente d’un scoop qu’on ne trouvera probablement pas dans des logs partiels.

  • Rotation des tokens GitHub, npm, cloud et registries.
  • Rotation des clés SSH utilisées par les développeurs ou pipelines.
  • Revue des secrets GitHub Actions, GitLab CI, Jenkins, Vault et variables d’environnement.
  • Invalidation des tokens longue durée et passage à des credentials à durée courte.
  • Recherche d’accès anormaux sur GitHub, npm, cloud providers et registries internes.

3. Durcir GitHub Actions et les workflows

Le pattern pull_request_target doit être traité avec prudence. Il est utile dans certains cas, mais dangereux quand il donne à du code sorti d’un fork une opportunité d’influencer un contexte privilégié.

  • Éviter d’exécuter du code non fiable dans un workflow privilégié.
  • Segmenter les workflows de test, build, signature et publication.
  • Restreindre fortement les permissions du GITHUB_TOKEN.
  • Limiter OIDC par branche, environnement, workflow, audience et claims attendus.
  • Désactiver les permissions par défaut trop larges.
  • Utiliser des environnements protégés pour les publications.
  • Réduire ou isoler les caches entre contexte fork et contexte base.

4. Surveiller le comportement à l’installation

La supply chain JavaScript a un vieux problème : les scripts de lifecycle. preinstall, install, postinstall et leurs amis permettent d’exécuter du code pendant l’installation. Pratique pour les builds natifs. Excellent pour les infostealers. Encore une grande victoire de la “developer experience”.

  • Limiter ou désactiver les scripts d’installation quand c’est possible.
  • Bloquer les accès réseau inattendus pendant les installations.
  • Détecter les lectures de fichiers sensibles : ~/.npmrc, ~/.ssh, ~/.aws, .docker/config.json.
  • Surveiller les accès aux variables d’environnement en CI.
  • Journaliser les commandes shell exécutées pendant les builds.

Le vrai diagnostic

Mini Shai-Hulud, ce n’est pas seulement une attaque npm, c’est un test à grande échelle de notre dépendance à l’automatisation “de confiance”.

Nous avons construit des chaînes de livraison où des milliers de dépendances sont résolues, installées et exécutées automatiquement, voire parfois publiées automatiquement. Ensuite, nous avons ajouté des signatures, des attestations et des badges de conformité pour mieux dormir.

Le problème n’est pas que ces contrôles sont inutiles, le problème c'est qu’ils ne compensent pas une frontière de confiance mal comprise.

La supply chain ne se sécurise pas uniquement en prouvant l’origine.

Elle se sécurise aussi en contrôlant ce que l’origine avait le droit de faire.

Mesures de défense prioritaires

Checklist opérationnelle

  • Geler temporairement les mises à jour automatiques des dépendances critiques.
  • Auditer les lockfiles et les caches de build.
  • Rebuilder depuis des runners propres et éphémères.
  • Faire tourner les secrets exposables.
  • Réduire les permissions GitHub Actions, npm et cloud.
  • Segmenter build, test, signature et publication.
  • Limiter les scripts lifecycle npm en CI.
  • Surveiller les accès sortants pendant les installations.
  • Mettre en place une allowlist stricte des packages critiques.
  • Traiter les runners CI/CD comme des actifs sensibles, pas comme des machines jetables sans valeur.

Quick Win : regarder les frontières de confiance

Pour savoir si votre organisation est exposée à ce type d’attaque, commencez par les questions simples :

  • Un workflow déclenché par une pull request peut-il influencer un workflow de publication ?
  • Un cache provenant d’un contexte non fiable peut-il être consommé dans un contexte privilégié ?
  • Les runners de build ont-ils accès à des secrets sans rapport avec leur tâche ?
  • Les publications npm utilisent-elles des identités trop larges ?
  • Les scripts d’installation ont-ils accès au réseau et aux secrets ?
  • Les attestations sont-elles vérifiées avec des politiques strictes, ou simplement regardées comme un badge rassurant ?

Si plusieurs réponses sont floues, ce n’est pas une posture de sécurité. C’est une invitation.

Conclusion

Mini Shai-Hulud confirme que l’attaquant moderne n’a plus besoin de casser la porte de production puisqu'il peut manipuler l’usine qui fabrique les clés.

La compromission d’un package npm est visible, la compromission d’une chaîne de publication légitime est plus subtile. Elle remet en cause les hypothèses sur lesquelles reposent les équipes développement, sécurité et plateforme.

La bonne réponse, si il y en a une, n’est pas de renoncer à OIDC, aux signatures ou à la provenance mais plutôt de les compléter par une vraie analyse des frontières de confiance, des permissions de pipeline, des secrets disponibles et du comportement au moment du build.

Dans la supply chain moderne, le pipeline est une surface d’attaque.

Et un npm install peut parfois ressembler à un pentest involontaire.