npm a lancé Package Provenance fin 2022. Pendant deux ans, l'adoption s'est stabilisée en moyenne entre 20 et 50 paquets par semaine. Puis est arrivé Trusted Publishing en 2024. Des articles de blog ont été rédigés. Des avis de la CISA ont été émis. L'indicateur a à peine bougé. Finalement, Trusted Publishing avec OIDC a été rendu généralement disponible en juillet 2025.
Puis Shai-Hulud a frappé. L'adoption hebdomadaire a bondi à 430 paquets. En 18 mois, l'adoption cumulée a été multipliée par 3,4. Nous n'en sommes toujours qu'à 25 % du volume total de téléchargements couvert, et seuls 11 001 des 51 370 principaux paquets l'ont adopté. Mais ces attaques ont fait bouger les lignes bien plus que tout ce qu'a pu faire l'industrie de la sécurité.
Voici les données.


Ce qu'est Trusted Publishing
Trusted Publishing remplace les jetons API npm de longue durée par des identifiants éphémères générés par exécution via OpenID Connect. Au lieu de stocker indéfiniment un NPM_TOKEN dans les secrets de votre dépôt GitHub, votre pipeline CI obtient un jeton qui expire en quelques minutes. Rien à voler. Rien à exfiltrer.
La vague d'attaques qui a tout changé
26 août 2025 : S1ngularity. Des attaquants ont exploité une mauvaise configuration de GitHub Actions dans le monorépertoire Nx pour exécuter du code provenant d'un fork malveillant dans le contexte de confiance du dépôt en amont, dérobant ainsi le jeton de publication npm. Des versions malveillantes de plusieurs paquets Nx ont été en ligne pendant quatre heures, analysant les machines des développeurs à la recherche d'identifiants, de clés SSH, de portefeuilles crypto — et cherchant notamment activement des outils CLI d'IA installés pour les exécuter avec --dangerously-skip-permissions et extraire le contenu du système de fichiers. Cette semaine-là, l'adoption a connu une hausse notable pour la première fois.
8 septembre 2025 : Debug/Chalk. Un mainteneur a été victime d'une attaque de phishing via un faux e-mail de support npm (provenant de npmjs.help) qui a dérobé ses identifiants et son code TOTP en direct. 18 paquets cumulant plus de 2 milliards de téléchargements hebdomadaires ont été piégés par une charge utile de vol de cryptomonnaie interceptant discrètement les interactions avec les portefeuilles de navigateur et redirigeant les fonds. Les versions malveillantes sont restées en ligne pendant deux heures. Cette semaine-là : 103 nouveaux paquets ont adopté le Trusted Publishing.
15 septembre 2025 : Vague 1 de Shai-Hulud. Un ver auto-réplicatif a touché l'écosystème npm. Lorsqu'un paquet compromis trouvait des jetons npm supplémentaires dans son environnement, il publiait automatiquement des versions malveillantes de tout ce qu'il pouvait atteindre. Résultat : plus de 700 paquets compromis, 27 000 dépôts GitHub malveillants, 14 000 secrets exposés répartis dans 487 organisations. La CISA a émis une alerte le 23 septembre. Cette semaine-là : 109 nouveaux paquets.
23 novembre 2025 : Shai-Hulud 2.0. Une PR (Pwn Request) contre le dépôt asyncapi/cli a exfiltré le jeton de CI en moins de trois minutes, puis l'a utilisé pour déployer le ver via une extension OpenVSX malveillante. La campagne s'est propagée à plus de 25 000 dépôts malveillants. Microsoft a publié des directives le 9 décembre. Cette semaine-là : 372 nouveaux paquets. La moyenne hebdomadaire des deux années précédentes était d'environ 40.
24 novembre 2025 : SHA1-Hulud. Une vague parallèle a touché Zapier, ENS Domains, et d'autres. Des identifiants à longue durée de vie ont été trouvés dans des dépôts compromis. L'équipe de sécurité de npm a explicitement recommandé le Trusted Publishing comme correctif. Cette semaine-là : 120 nouveaux paquets.
20–21 mars 2026 : CanisterWorm. TeamPCP a déployé un ver npm via des jetons volés. Plus de 28 paquets infectés en moins de 60 secondes ; la charge utile a récolté des identifiants et s'est auto-propagée. Cette semaine-là : 112 nouveaux paquets.
31 mars 2026 : Axios. Sapphire Sleet (Corée du Nord) a compromis un compte de mainteneur et a publié deux versions compromises à 39 minutes d'intervalle, chacune injectant une fausse dépendance qui a téléchargé silencieusement un cheval de Troie d'accès à distance multiplateforme. Les paquets malveillants sont restés en ligne pendant trois heures. Axios compte plus de 100 millions de téléchargements hebdomadaires. Cette semaine-là : 138 nouveaux paquets.
8–22 avril 2026 : CanisterSprawl. Un second ver npm de TeamPCP utilisant un nouveau canister ICP. Lorsque des jetons PyPI ont été découverts dans des environnements infectés, il a sauté d'un écosystème à l'autre via une injection .pth. Cette semaine-là : 163 nouveaux paquets.
29–30 avril 2026 : Mini Shai-Hulud I. TeamPCP est passé du vol de jetons au vol d'identifiants de CI. Une attaque inter-écosystème a frappé npm, PyPI et Packagist en 24 heures via des jetons CircleCI compromis. Cette semaine-là : 121 nouveaux paquets.
7–11 mai 2026 : Mini Shai-Hulud II / TanStack. Voici l'escalade qui change tout : ils n'ont pas volé de jeton. TeamPCP a utilisé une PR (Pwn Request) pour empoisonner le cache GitHub Actions, puis a attendu que le flux de travail de version légitime s'exécute. Lorsque cela s'est produit — avec les permissions id-token: write — le code contrôlé par l'attaquant issu du cache empoisonné a extrait le jeton OIDC de la mémoire du runner et l'a échangé via le propre point de terminaison de jetons de npm. Les paquets publiés comportaient des attestations de provenance SLSA Build Level 3 valides. Le Trusted Publishing n'a pas été contourné. Il a été utilisé comme vecteur d'attaque. Plus de 170 paquets sur npm et PyPI en 5 heures.
18–19 mai 2026 : Mini Shai-Hulud III / Nx & AntV. L'extension Nx Console pour VS Code a été compromise en utilisant des identifiants volés lors de l'attaque TanStack — avec un temps de séjour de cinq jours avant utilisation. 639 versions npm de @antv ont été empoisonnées via un compte de mainteneur volé, chacune installant une porte dérobée persistante de type kitty-monitor. Cette semaine-là : 144 nouveaux paquets. La semaine suivante : 430. Un record absolu.
1er–7 juin 2026 : Miasma / Hades. La typologie des attaques a encore évolué. La vague 1 a publié 90 versions npm malveillantes ciblant les paquets Red Hat Cloud Services — non pas en volant des jetons OIDC, mais en abusant directement du point de terminaison de publication OIDC. La vague 2 a ajouté une technique binding.gyp pour contourner la détection des scripts d'installation. Dès la vague 4 (Hades), la campagne s'était propagée à PyPI via l'exécution au démarrage .pth, empoisonnant 37 wheels répartis sur 19 paquets. Red Hat a émis l'avis RHSB-2026-006. Cette semaine-là : 209 nouveaux paquets.
Le schéma et son amplification
Les premières attaques suivaient un scénario bien connu : piéger un mainteneur par phishing, voler un jeton à longue durée de vie, publier un malware, puis contaminer tout ce que le jeton pouvait atteindre. Debug/Chalk était une attaque par phishing. Axios découlait d'un compte de mainteneur compromis.
Cependant, les attaques les plus sophistiquées s'en sont pris directement au pipeline de CI. S1ngularity et Shai-Hulud 2.0 ont tous deux exploité des PR (Pwn Requests), c'est-à-dire des pull requests malveillantes qui exploitaient des workflows GitHub Actions pull_request_target vulnérables pour exécuter le code de l'attaquant dans le contexte de confiance du dépôt amont. Nul besoin de voler un jeton stocké : il suffisait que le runner de CI en possède un.
Mini Shai-Hulud II a marqué l'aboutissement logique de cette progression. Dès lors que l'on contrôle le runner, il devient possible d'extraire n'importe quel identifiant ambiant disponible, y compris les jetons OIDC à courte durée de vie. Les paquets ainsi publiés paraissaient parfaitement légitimes à tous les contrôles automatisés : provenance valide, véritable identité du mainteneur, signature correcte. L'attaque est passée de l'exploitation de secrets stockés à celle du processus de compilation lui-même.
Miasma a poussé l'escalade encore plus loin. Il n'était même plus nécessaire d'extraire un jeton : l'attaque exploitait directement le point de terminaison de publication OIDC. Chaque vague introduisait une nouvelle technique pour contourner la détection. Les analyses post-mortem pointaient inlassablement les mêmes défaillances, tandis que les attaques trouvaient continuellement de nouveaux moyens de contourner les correctifs recommandés.
La surface d'attaque est aujourd'hui nettement plus restreinte qu'il y a 18 mois. Non pas parce que l'industrie de la sécurité a su convaincre, mais parce que des packages ont été compromis par des portes dérobées, poussant les mainteneurs à modifier leur configuration.
Ce n'est pas une victoire pour l'éducation à la sécurité, mais plutôt un constat sur la manière dont les décisions en la matière sont réellement prises en pratique.
Qui était-ce ?
Durant la campagne Shai-Hulud 2.0, l'attaquant a renommé son compte GitHub en UnknownWonderer1, une référence évidente aux Zensunnis de Dune : ces nomades persécutés devenus les Fremen, la seule culture ayant appris à vivre en harmonie avec Shai-Hulud. Ce nom ne doit rien au hasard d'une intrusion fortuite dans l'écosystème, il témoigne d'une réflexion approfondie.
La conception du malware confirme cette lecture. S1ngularity n'a pas exfiltré discrètement des identifiants : il a injecté une commande d'arrêt dans le profil du shell, provoquant un plantage visible de la machine dès la prochaine ouverture d'un terminal. Ce n'est pas le comportement de quelqu'un cherchant à rester discret. Chaque campagne est restée bien en deçà de son potentiel destructeur. Un ver capable de se propager automatiquement à plus de 700 packages tout en bridant sa charge utile fait un choix délibéré.
Ils comprenaient également la structure des incitations bien mieux que l'écosystème lui-même. Les mainteneurs sont rarement rémunérés pour sécuriser leurs packages. L'impact d'une faille pèse sur les utilisateurs en aval, et non sur la personne qui a laissé un jeton d'accès dans sa CI. Les plateformes ayant le pouvoir d'imposer des publications sécurisées sont celles qui subissent le moins les conséquences en cas de problème. Il s'agit d'une défaillance classique d'action collective — et 40 000 packages non protégés après trois ans d'avis de sécurité illustrent parfaitement le résultat de cette structure. Cet attaquant a compris pourquoi rien ne bougeait et a décidé d'appliquer une autre forme de pression.
Tirs de sommation
J’avais déjà abordé ce sujet à l’époque: le choix du nom, la retenue dont faisait preuve la conception du logiciel malveillant, et la manière dont les attaques s’arrêtaient systématiquement avant d’aller jusqu’au bout de leur exploitation. À mon sens, Shai-Hulud n’était pas avant tout une opération criminelle. C’était un message — envoyé par quelqu’un qui comprenait suffisamment bien l’écosystème pour savoir exactement quels points sensibles le feraient réagir.
Les Fremen prient pour que le passage du Créateur purifie le monde. L'agresseur semble être parvenu à une conclusion similaire : seule une souffrance visible pourrait contraindre l'écosystème à affronter ce qui a rendu le ver possible. Pour les Fremen, Shai-Hulud n'est pas simplement un animal destructeur. C'est le Créateur. Son passage déchire le désert, mais il purifie également et fait respecter les lois auxquelles tout ce qui vit dans cet écosystème doit se plier.
Ils ne se sont pas contentés de libérer Shai-Hulud.
Ils ont choisi d'incarner le Vagabond qui comprenait pourquoi il devait venir.
Pourquoi nous n'avons toujours pas résolu ce problème
L'alerte avait été lancée. L'écosystème n'a pas réagi assez vite. Le guide d'attaque open source « Shai-Hulud » a alors été repris par des acteurs qui n'avaient aucun intérêt à faire passer un message : TeamPCP, Sapphire Sleet et d'autres qui se sont directement attaqués au vol d'identifiants, aux portefeuilles cryptographiques et à l'accès à distance. Des frameworks comme Mastra en ont fait les frais. Le ver qui n'était au départ qu'une démonstration est devenu un modèle à suivre.
Ce qui est frustrant, c’est que cet obstacle n’est pas d’ordre technique. Trusted Publishing est gratuit et ne prend que dix minutes. Le problème, c’est que le coût de ne pas le faire n’a pas encore été imputé à la bonne personne. Les responsables de paquets assument le risque de réputation si leur paquet est compromis, mais le préjudice réel se répercute en aval sur des équipes qui n’ont pas écrit une seule ligne du paquet concerné. Ce décalage est structurel. Les attaques entraînent un pic d’adoption temporaire, puis l’urgence s’estompe, et la prochaine vague de paquets revient par défaut à des jetons à longue durée de vie.
Regardez le graphique. Les pics sont bien réels. Tout comme la baisse qui les sépare.
Et Mini Shai-Hulud a apporté un nouvel élément : même les paquets qui ont adopté Trusted Publishing peuvent être compromis si le pipeline de CI sous-jacent n'est pas sécurisé. Extraire un jeton OIDC de la mémoire d'un runner est plus difficile que de voler un secret stocké. Mais ce n'est pas impossible, et cette attaque dispose désormais d'une preuve de concept publique. Trusted Publishing élimine un vecteur d'attaque. Il ne les élimine pas tous.
Le fossé de la responsabilité, et que faire à ce sujet
Axios enregistrait plus de 100 millions de téléchargements par semaine et n'avait pas adopté Trusted Publishing avant qu'un acteur nord-coréen ne le compromette. N'importe qui aurait pu soumettre une PR un an plus tôt. Personne ne l'a fait.
C'est cela, le fossé de la responsabilité. La communauté de la sécurité publie des bulletins, rédige des analyses post-mortem et attend la prochaine attaque pour faire bouger les choses. Il existe une version plus constructive de cette même pression : s'attaquer de manière proactive aux 40 000 paquets qui n'ont pas encore fait la transition, de la même manière que Let's Encrypt s'est attaqué à HTTP. Soumettez des PR. Ouvrez des tickets. Nommez les paquets à fort volume de téléchargement qui utilisent encore des jetons à longue durée de vie. Faites en sorte que le coût social de ne pas adopter TP soit supérieur aux dix minutes nécessaires pour corriger le problème.
C'est le genre d'activisme dont l'écosystème a réellement besoin. Pas d'un autre avis de la CISA. Pas d'un autre article de blog lu puis oublié. Une pression spécifique, ciblée et inconfortable sur les mainteneurs de paquets précis — ceux qui affichent plus de 10 millions de téléchargements hebdomadaires et qui se trouvent toujours à un identifiant hameçonné d'écart de devenir le prochain incident.
L'industrie de la sécurité connaît la solution depuis trois ans. La question est de savoir si nous sommes prêts à faire en sorte qu'il soit socialement inacceptable de l'ignorer.
40 000 des 51 000 principaux paquets n'ont toujours pas fait la transition
11 001 paquets ont adopté Trusted Publishing. Ces 11 000 paquets représentent environ 25 % du volume total des téléchargements, car certains des plus grands paquets ont basculé après chaque vague d'attaques. Mais cela laisse 40 369 paquets (75 % du volume de téléchargement) qui publient encore avec des jetons à longue durée de vie.
Si vous maintenez un paquet npm, faites-le dès maintenant. La documentation est ici. Quatre lignes de YAML et une case à cocher. Assurez-vous ensuite que vos flux de travail GitHub Actions n'utilisent pas pull_request_target sans limites de confiance explicites, car c'est le vecteur qu'a utilisé Mini Shai-Hulud pour extraire le jeton OIDC même après la mise en place de TP.
Si vous dépendez de paquets qui n'ont pas fait la transition, signalez un problème. Ouvrez une PR. Le mainteneur ne sait peut-être pas que Trusted Publishing existe, ou a simplement besoin que quelqu'un rende l'inaction plus inconfortable que la correction de dix minutes.
Le ver des sables dans Dune s'appelle Shai-Hulud, ce qui signifie « le grand vieillard du désert ». Les Fremen ne se réjouissent pas lorsqu'il détruit quelque chose. Ils comprennent que son passage façonne l'écosystème d'une manière que rien d'autre ne peut faire.
C'est la vérité inconfortable au cœur de cet article. Les attaques ont fonctionné. La douleur a fait bouger les choses d'une manière que trois ans d'avis n'ont pas pu faire.
Nous avons retenu la leçon. L'écosystème évolue sous la pression, et celle-ci ne doit pas nécessairement provenir d'un ver. The Wanderer comprenait pourquoi le Créateur devait venir. Nous travaillons pour faire en sorte que le prochain ne soit plus nécessaire.
Plus d'informations à ce sujet bientôt.