Mai 2026 : la vague
Trois épisodes résument la première secousse.
Le 11 mai, une attaque coordonnée a injecté 404 versions malveillantes dans plus de 170 packages npm : tout l'écosystème TanStack (42 packages), les SDK de Mistral AI, l'outillage UiPath (65 packages), OpenSearch (1,3 million de téléchargements par semaine) et Guardrails AI. L'un des plus larges événements d'empoisonnement de registre observés à ce jour.
Le 14 mai, trois versions piégées de node-ipc (une brique fondamentale de communication inter-processus, plus de 10 millions de téléchargements hebdomadaires) ont été publiées simultanément, chacune embarquant une charge utile de ~80 Ko volant des identifiants.
En toile de fond, l'attaque sur axios (31 mars) : compromission des identifiants npm du mainteneur principal, attribuée à un acteur étatique nord-coréen, puis publication de deux releases backdoorées.
Le schéma se répète. On vole un token npm ou un Personal Access Token (PAT) GitHub, on republie un package légitime avec une porte dérobée, et la CI (Continuous Integration, l'intégration continue qui build le code automatiquement) de milliers de projets l'installe sans la moindre alerte.
Juin 2026 : quand même la provenance ne suffit plus
Si mai a montré qu'on pouvait voler un token pour republier un package, juin a montré pire : qu'on pouvait le faire sans déclencher la moindre alerte.
Le 1er juin, l'attaque baptisée Miasma (une nouvelle variante du ver auto-propagateur Shai-Hulud) a compromis 32 packages publiés sous le périmètre @redhat-cloud-services, soit l'essentiel de l'écosystème JavaScript de la Red Hat Hybrid Cloud Console, pour près de 10 millions de téléchargements cumulés. En une fenêtre de 72 secondes, l'acteur a publié les 32 versions empoisonnées, très probablement par automatisation. Chaque payload se déclenchait via un hook preinstall et siphonnait les identifiants AWS, GCP, Azure et Kubernetes.
Deux détails rendent Miasma plus inquiétant que les épisodes de mai.
D'abord, aucune CVE n'a été émise. Les scanners qui dépendent des bases de vulnérabilités connues (Common Vulnerabilities and Exposures) avaient donc zéro surface de détection. Le mal était déjà installé sur les runners de CI avant qu'une signature de menace n'existe.
Ensuite, toutes les versions malveillantes ont passé la validation « Trusted Publishing » via des tokens OIDC légitimes. Autrement dit, l'attestation de provenance, censée prouver qu'un package vient bien de son pipeline d'origine, a été produite correctement, par un pipeline lui-même compromis.
La leçon n'est pas que la provenance et le scan sont inutiles. C'est qu'aucune mesure prise isolément n'est un garde-fou suffisant. Un attaquant qui contrôle le pipeline de publication peut cocher la case « signé et vérifié ». La provenance prouve d'où vient un package, jamais qu'il est sain. D'où la checklist qui suit, pensée comme une défense en profondeur plutôt qu'une ligne Maginot.
Pourquoi les développeurs sous-estiment le risque
Un projet Node moyen tire des centaines à des milliers de dépendances transitives. On audite le code qu'on écrit, jamais celui qu'on installe. Pire : npm install exécute par défaut des scripts arbitraires (postinstall, preinstall) au moment de l'installation, sur la machine du dev comme sur le runner de CI. Le maillon faible n'est pas votre code, c'est la confiance implicite accordée à tout l'arbre de dépendances.
La checklist Tech Lead
1. Verrouiller les versions
Committez le package-lock.json et buildez avec npm ci plutôt que npm install.
# npm ci installe EXACTEMENT le lockfile, sans résolution de version surprise
npm ci --ignore-scripts
npm ci échoue si le lockfile et le package.json divergent. C'est exactement le garde-fou qu'on veut en CI.
2. Désactiver les scripts d'installation
La majorité des payloads se déclenchent via un script postinstall ou preinstall. C'est précisément le vecteur de Miasma. Désactivez-les par défaut et n'autorisez explicitement que ceux dont vous avez besoin.
# .npmrc
ignore-scripts=true
3. Brancher un outil de SCA
Le Software Composition Analysis (SCA) analyse en continu vos dépendances pour détecter packages malveillants, typosquatting et CVE connues. Socket, Snyk ou l'open-source OSV-Scanner s'intègrent en quelques minutes dans une pipeline.
# Exemple GitHub Actions
- name: Audit dépendances
run: npx osv-scanner --lockfile=package-lock.json
Une limite à connaître : un SCA basé sur les CVE connues ne voit pas une attaque zero-day comme Miasma, où aucune CVE n'est publiée. Privilégiez les outils qui font aussi de l'analyse comportementale (détection de scripts d'install suspects, exfiltration réseau, accès aux credentials), ce que Socket met justement en avant. Et ne traitez jamais « le SCA est vert » comme une preuve d'innocuité.
4. Vérifier la provenance
npm supporte désormais les attestations de provenance (signature liée au commit et au build d'origine). Préférez les packages qui les publient, et générez-les pour vos propres packages avec npm publish --provenance.
Attention quand même au faux sentiment de sécurité. Miasma a généré des attestations de provenance valides via des tokens OIDC légitimes, depuis un pipeline compromis. La provenance prouve d'où vient un package, jamais qu'il est sain. C'est une couche utile, pas une garantie. Combinez-la systématiquement avec les points 5 et 6.
5. Cloisonner les secrets en CI
Un payload moderne cible en priorité vos tokens npm et PAT GitHub pour se republier tout seul. Concrètement :
- jetons à périmètre minimal et courte durée de vie ;
- pas de secret « large scope » exposé à l'étape
install; - runners isolés, sans accès réseau sortant inutile pendant le build (Miasma exfiltrait justement vos credentials cloud vers l'extérieur depuis le runner).
6. Mettre en place un délai de quarantaine
C'est la mesure la plus rentable de la liste, parce qu'elle est passive : vous ne scannez rien, vous attendez. Quand un package est compromis, la version piégée est repérée et retirée du registre en quelques heures, rarement plus de 24 à 48 h. Si votre install refuse toute version publiée il y a moins de quelques jours, vous ne téléchargez jamais la fenêtre dangereuse. Vous profitez de la vigilance de la communauté sans rien surveiller vous-même.
Depuis le CLI npm 11.10.0 (février 2026), le réglage est natif. Il s'écrit dans le .npmrc du projet, valeur en jours, et se committe pour couvrir toute l'équipe et la CI :
# .npmrc
min-release-age=3
Sur pnpm, le même réglage s'appelle minimumReleaseAge et s'exprime en minutes, dans pnpm-workspace.yaml :
# pnpm-workspace.yaml
minimumReleaseAge: 4320 # 3 jours
minimumReleaseAgeExclude:
- '@mon-org/*' # vos packages privés à exempter
Attention à un piège : ce délai s'applique au moment du install, pas quand un bot comme Renovate ou Dependabot ouvre une PR de mise à jour. Ces outils ont leur propre réglage de cooldown (minimumReleaseAge chez Renovate, cooldown.default-days chez Dependabot), à configurer séparément. Vérifiez aussi que la version du gestionnaire de paquets réellement utilisée (pin via packageManager, Corepack, image Docker ou setup-node) est assez récente pour supporter le réglage, sinon toute la config reste inerte.
Face à une attaque qui a empoisonné 32 packages en 72 secondes, ce simple délai fait souvent la différence entre « on a esquivé » et « on est compromis ».
Conclusion
La chaîne d'approvisionnement est devenue la première surface d'attaque de l'écosystème JavaScript. Miasma l'a rappelé brutalement en juin : à l'ère des pipelines compromis, « signé et vérifié » n'est plus synonyme de « sûr ». Aucune des mesures ci-dessus n'est révolutionnaire, et aucune n'est suffisante seule. Mais empilées, elles transforment une confiance aveugle en défense en profondeur, où chaque contrôle couvre l'angle mort du suivant. Pour un Tech Lead, formaliser cette hygiène n'est pas un luxe sécuritaire. C'est une décision d'architecture qui protège l'équipe, le produit et la production.
Et vous, où en est votre pipeline ? Si vous voulez un audit de votre chaîne d'appro Node/CI-CD, parlons-en.
Sources
- Wiz, Miasma: Supply Chain Attack Targeting RedHat npm Packages : https://www.wiz.io/blog/miasma-supply-chain-attack-targeting-redhat-npm-packages
- Microsoft Security Blog, Malicious npm packages abuse dependency confusion : https://www.microsoft.com/en-us/security/blog/2026/05/29/33-malicious-npm-packages-abuse-dependency-confusion-profile-developer-environments/
- Unit 42 (Palo Alto Networks), The npm Threat Landscape : https://unit42.paloaltonetworks.com/monitoring-npm-supply-chain-attacks/