Shai hulud - Paquets npm - Attaque de la chaîne d'approvisionnement

Shai-Hulud : Le ver des paquets npm expliqué

TL; DR

Le 14 septembre 2025, des chercheurs ont identifié Shai Hulud, un ver auto-réplicateur caché à l'intérieur paquets npm, transformant une mise à jour de dépendance de routine en une mise à jour à grande échelle attaque de la chaîne d'approvisionnement. Repéré pour la première fois dans le @ctrl/tinycolor Shai-Hulud, un paquet de Daniel dos Santos Pereira, collecte des secrets, les exfiltre via les dépôts et les workflows GitHub, et se republie dans le registre à l'aide d'identifiants volés. En quelques jours, le nombre de paquets infectés est passé de quelques dizaines à des centaines, confirmant ainsi que Shaihulud ce n’est pas simplement un autre cheval de Troie, mais un ver conçu pour se propager automatiquement dans l’écosystème npm.

Impact: tout développeur ou exécuteur CI installant des packages npm publics est en danger.

Actions immédiates: bloquez les versions connues, passez aux installations uniquement avec fichier de verrouillage, faites pivoter les jetons npm et GitHub, auditez les flux de travail et surveillez les indicateurs de compromission (IoC).

Que se passe-t-il?

L'espace Attaque de la chaîne d'approvisionnement Shai-Hulud dans les packages npm est l'un des incidents les plus perturbateurs de ces dernières années. Contrairement aux chevaux de Troie isolés, ce ver se propage vol d'identifiants, exfiltration automatisée et auto-réplication. Par conséquent, la durée de l’infection est passée de quelques semaines à quelques heures seulement.

Pour les équipes DevOps, la leçon est claire : si chaque installation peut exécuter du code, alors chaque mise à jour de dépendance est un point de violation potentiel.

Vecteur initial possible et informations d'identification ciblées

Analyse précoce indique que l'attaque a probablement commencé avec identifiants volés. Par exemple, les campagnes de phishing usurpant l'identité de npm login Les invites MFA ont peut-être capturé des jetons de développeur. Une fois cette première intrusion établie, le ver s'est propagé en s'intégrant aux paquets npm et en dérobant d'autres secrets :

  • fichiers de configuration npm comme .npmrc, contenant souvent des jetons de publication.
  • Variables d'environnement et configurations avec GitHub PATs et CI/CD des secrets.
  • Points de terminaison des métadonnées cloud (AWS, GCP, Azure) produisant des informations d'identification de courte durée pour le mouvement latéral.

Le vol d'identifiants est donc devenu le tremplin. Grâce à des jetons npm valides et à des secrets GitHub, Shai-Hulud pouvait s'auto-répliquer sur plusieurs packages et dépôts sans intervention humaine supplémentaire.

Impact de l'attaque de la chaîne d'approvisionnement de Shai-Hulud sur les dirigeants

Shai-Hulud est toujours actif aujourd'hui. Ce ver accélère la chronologie des effets. Ce qui prenait autrefois des semaines avec un cheval de Troie se déploie désormais en quelques heures. Résultat : la propagation est plus rapide et plus difficile à contenir. Elle avance par :

  • Vol de jetons de publication npm et de secrets GitHub.
  • Se rééditer dans d'autres packages npm.
  • Ajout de workflows d'actions GitHub malveillants pour la persistance.

Qui est affecté:

Toute équipe installant des packages npm publics est exposée. De plus, les développeurs utilisant des jetons npm ou GitHub en cache sont exposés à un risque élevé. Les exécuteurs d'intégration continue utilisant des secrets à large portée sont également vulnérables.

Risque commercial

L'impact commercial est rapide. Le vol de jetons peut entraîner le piratage de comptes, le détournement de packages et même une utilisation abusive du cloud. De plus, la persistance des workflows GitHub complique leur nettoyage. Par conséquent,, les équipes doivent traiter Shai-Hulud comme un incident en cours, et non comme un incident clos.

Comment fonctionne l'attaque de la chaîne d'approvisionnement Shai-Hulud dans les packages npm

Objectifs et motivation de l'attaquant

La campagne est optimisée pour trois choses :

  • Le premier objectif est de voler des informations d'identification à grande échelle Depuis les ordinateurs portables des développeurs et les exécuteurs CI. Cela inclut les jetons de publication NPM, les jetons GitHub et les identifiants cloud. De fait, plusieurs analyses confirment une collecte systématique de secrets, comme l'exécution de TruffleHog et l'interrogation des points de terminaison des métadonnées cloud.
  • Le deuxième objectif est de se propager automatiquement en abusant des droits de publication des mainteneurs compromis. Par conséquent, une intrusion peut rapidement se multiplier, car de nouvelles versions infectées d'autres paquets apparaissent sans intervention humaine supplémentaire.
  • Le troisième objectif est de persister et s'exfiltrer de manière fiable via l'infrastructure GitHub. Les attaquants créent un dépôt public nommé « Shai-Hulud » avec une double base64 données.json, et en plus ils installent un workflow qui sérialise ${{ toJSON(secrets) }} et le publie sur un webhook statique.

Les bénéfices probables incluent un accès durable aux registres et au code source, une migration latérale rapide vers des comptes cloud et la possibilité de militariser davantage la chaîne d'approvisionnement. Des rapports publics montrent que des dépôts privés ont été transférés vers le public avec une "-migration" suffixe, qui augmente l'exposition et l'élan des données

À l'intérieur de la charge utile Shai-Hulud : bundle.js dans les packages npm

Shai-Hulud est livré en tant que grand, regroupé dans Webpack et fortement minifié fichier JavaScript (bundle.js, environ 3–3.7 Mo) qui s'exécute à partir d'un post-installation accrocher package.json. Par conséquent, Chaque installation déclenche automatiquement la charge utile. Cette conception masque les identifiants, compresse le flux de contrôle et centralise toute la logique dans un seul artefact qui s'exécute pendant l'installation. Les analystes confirment systématiquement le regroupement de Webpack, la taille inhabituelle des fichiers et l'exécution au moment de l'installation.

Caractéristiques d'obfuscation et d'anti-analyse que vous verrez dans les échantillons :

  • Graphique de module minifié avec des identifiants de module numériques, des commentaires clairsemés et un flux de contrôle aplati., cette structure rend la révision manuelle extrêmement difficile.
  • Masquage de chaîne via des calques base64 et des aides à la construction. Par exemple, l'encodage et le décodage répétés en base64 apparaissent généralement autour des routines d'exfiltration.
  • Répartition dynamique à travers eval-modèles de style et corps de fonction générés, permettant ainsi au code de modifier le comportement au moment de l'exécution.
  • Filtrage du système d'exploitation privilégier l'exécution Linux et macOS, en particulier sur les exécuteurs CI et les ordinateurs portables des développeurs.

D’un point de vue fonctionnel, le bundle est modulaire. Les articles décrivent des modules pour la découverte du système d'exploitation, l'analyse du système de fichiers et des secrets Git, l'accès au SDK cloud, les opérations sur l'API GitHub et un moteur de propagation qui modifie les autres paquets appartenant au mainteneur. D'ailleurs, StepSecurity et ReversingLabs mettent tous deux en avant une fonction qui met automatiquement à jour les paquets avec le hook malveillant.

Exécution lors de l'installation dans Shai-Hulud : comment les paquets npm déclenchent le ver

L'attaque commence lorsque postinstall exécute le nœud bundle.js. À ce stade, le script initialise et décompresse l'état de fonctionnement en mémoire, préparant le terrain pour le fonctionnement complet du ver.

Découverte et récolte

  • La charge utile vide le fichier process.env et analyse les fichiers locaux à la recherche de secrets à haute entropie et de préfixes de jetons. De plus, elle étend la couverture en exécutant TruffleHog.
  • Il interroge les points de terminaison des métadonnées du cloud pour collecter des informations d'identification de courte durée. , par exemple en : appelle à 169.254.169.254 sur AWS ou metadata.google.internal sur GCP apparaissent souvent chez les hôtes infectés.
  • En conséquence, toute information d'identification trouvée devient immédiatement utilisable pour publier de nouveaux packages npm ou pousser des workflows GitHub.

exfiltration

  • Le ver crée un nouveau dépôt GitHub nommé Shai Hulud et écrit un double encodé en base64 data.json avec des détails sur la plateforme, des informations sur l'environnement et des secrets. Comme on peut le constater, ce comportement bruyant est facile à repérer si les défenseurs savent où chercher.
  • Il installe également un flux de travail GitHub Actions, souvent sur une branche nommée shai-hulud, qui sérialise ${{ toJSON(secrets) }} et publie les données sur un webhook statique. De plus, ce flux de travail persiste jusqu'à ce qu'il soit supprimé.

Propagation

  • À chaque jeton npm découvert, la charge utile énumère tous les paquets appartenant au mainteneur compromis. Ensuite, elle récupère chaque archive tar, injecte bundle.js et une entrée post-installation, puis republie le paquet.
  • En conséquence, des dizaines de colis infectés peuvent apparaître en quelques heures, multipliant le rayon d’explosion à travers l’écosystème.

Persistance et exposition

  • Le ver maintient les flux de travail malveillants en vie et, dans plusieurs cas, transforme les dépôts privés en dépôts publics avec un "-migration" Suffixe. Au total, cela permet à l'attaquant de conserver une position dominante et de maximiser la fuite de données.

Note de détection de clé
Cette utilisation inhabituelle de ${{ toJSON(secrets) }} dans les workflows Actions, c'est rare. Par conséquent, les équipes devraient le traiter comme un indicateur de signal élevé pendant les chasses.

Modèle de flux de travail aseptisé que vous devriez rechercher

Cette utilisation inhabituelle de à JSON(secrets) Les actions sont un indicateur de signal élevé dans cet incident.

Pseudo-code de propagation de haut niveau (sûr, descriptif)

async function propagate(token, owner) {
  const pkgs = await npmApi.listPackages(owner, token);
  for (const p of pkgs) {
    const tgz = await npmApi.fetchTarball(p, token);
    const modified = injectBundleAndPostinstall(tgz); // adds bundle.js + "postinstall"
    await npmApi.publish(modified, token);            // publishes new malicious version
  }
}

Les analystes ont observé cette boucle à grande échelle, ce qui explique le passage rapide de dizaines à des centaines de paquets infectés.

Pourquoi est-ce un ver dans un écosystème d'emballage ?

Un ver est un logiciel malveillant qui se propage de lui-même sans intervention manuelle à chaque étape. Dans les systèmes d'exploitation, les vers exploitent généralement les vulnérabilités du réseau pour se propager d'une machine à une autre. À l'inverse, Shai-Hulud opère dans le registre npm. Son chemin d'accès efficace passe par réutilisation des informations d'identification.

Le ver exploite les jetons de publication npm volés. Dès qu'il obtient des identifiants valides, il republie les versions infectées sous d'autres paquets appartenant au même mainteneur. Ces paquets sont ensuite installés par des développeurs ou des exécuteurs d'intégration continue sans méfiance, et le cycle se répète.

Pour cette raison, les analystes de sécurité, y compris Lecture sombre, classent Shai-Hulud comme un ver autoréplicateur plutôt qu'un simple cheval de Troie ou un incident de typosquatting. La différence est importante : un cheval de Troie compromet généralement un hôte, tandis qu'un ver amplifie automatiquement son impact sur l'ensemble d'un écosystème.

Aide-mémoire « Comment ça marche »

Pour résumer le cycle de vie de Shai-Hulud, voici une arnaquecisla décomposition de ses principales étapes :

  • Un paquet avec post-installation est installé, et bundle.js exécute.
  • La charge utile vide les variables d'environnement, analyse les fichiers et l'historique git, s'exécute TruffeHoget interroge les services de métadonnées cloud. Par conséquent, tout secret découvert devient immédiatement utile.
  • L'exfiltration se produit de deux manières : d'abord, en créant un dépôt public nommé Shai Hulud avec un double codage en base64 data.json; deuxièmement, en implantant un flux de travail GitHub Actions qui publie ${{ toJSON(secrets) }} à un webhook.
  • À l'aide d'un jeton npm volé, le ver republie tous les autres paquets appartenant au mainteneur compromis avec le même hook malveillant. De cette façon, l'infection se multiplie rapidement.
  • Finalement, l'attaquant détient plus de secrets, plus de paquets à diffuser et persistance dans les comptes et référentiels GitHub.

Comment éviter ce type d'attaque, concrètement

Shai-Hulud est un signal d'alarme. Un ver qui vole des jetons et se réédite n'est pas un risque futur, il est présent dans le écosystème des packages npm aujourd'hui. Pour éviter ce type de attaque de la chaîne d'approvisionnement, les équipes ont besoin de contrôles programmables, automatisés et appliqués directement dans CI/CD pipelines. Ce sont les mêmes défenses que vous pouvez déjà mettre en œuvre avec Xygéni.

Arrêtez les mauvais artefacts à la porte

Vous devez analyser les packages et archives tar npm avant qu'ils n'atteignent les développeurs ou les tâches d'intégration continue. bundle.js fichiers, post-installation suspecte hooks, et les marqueurs d'obfuscation servent tous de signaux d'alarme précoces. De plus, l'application de périodes de réflexion et de versions épinglées pipelines empêche la consommation automatique de nouvelles versions non vérifiées.

Harden CI/CD par défaut

Guardrails in CI/CD sont essentiels. Ils rejettent les fusions ou installations introduisant de nouveaux scripts ou binaires. Parallèlement, ils bloquent les workflows qui sérialisent des secrets ou tentent des publications externes. Les équipes doivent également exiger des installations exclusivement basées sur des fichiers de verrouillage (npm ci) dans tous les pipelineafin que les ensembles de dépendances restent reproductibles et sûrs.

Réduire le rayon d'explosion du jeton

Les secrets ne doivent pas devenir des points de défaillance uniques. Analysez en permanence le code, les configurations et pipeline sortie pour informations d'identification exposéesLes jetons doivent être limités, leur durée de vie doit être courte et leur utilisation doit être renouvelée automatiquement lorsqu'une exposition est détectée. En règle générale, tout jeton utilisé sur un hôte ayant exécuté une opération de post-installation suspecte doit être considéré comme compromis.

Observez le comportement des vers tôt

Détection d'une anomalie C'est essentiel. Par exemple, des pics soudains d'événements de publication npm, l'apparition injustifiée de nouveaux workflows ou l'apparition de dépôts publics contenant des fichiers étrangement codés peuvent tous signaler une activité de ver. Par conséquent, les équipes doivent rapidement alerter et isoler les mainteneurs ou les exécuteurs qui présentent ces signes avant-coureurs.

Réparer rapidement sans interrompre les builds

La vitesse et la sécurité doivent aller de pair. Automatisé pull requests peut remplacer les paquets npm compromis par des versions validées. De plus, accessibilité et exploitabilité L'analyse garantit que les mises à niveau restent minimales et stables. Enfin, reconstruisez les exécuteurs CI affectés à partir d'images propres une fois l'exposition confirmée, empêchant ainsi la propagation de l'attaque.

Indicateurs de compromis (IoC)

Lors de l'analyse de Shai-Hulud, les équipes doivent surveiller les deux IoC statiques dans les fichiers et indicateurs de compromis comportementaux in pipelines. Ensemble, ces signaux aident à détecter les infections à un stade précoce et à réagir avant que le ver ne se propage davantage.

IoC statiques

Les condensés SHA-256 suivants correspondent aux résultats observés bundle.js échantillons:

  • 46faab8ab153fae6e80e7cca38eab363075bb524edd79e42269217a083628f09
  • 81d2a004a1bca6ef87a1caf7d0e0b355ad1764238e40ff6d1b1cb77ad4f595c3
  • dc67467a39b70d1cd4c1f7f7a459b35058163592f4a9e8fb4dffcbba98ef210c

De plus, soyez attentif à ces schémas récurrents :

  • A bundle.js à la racine du paquet.
  • "postinstall": "node bundle.js" à l'intérieur package.json.
  • Dépôts nommés Shai Hulud.
  • Workflows GitHub contenant ${{ toJSON(secrets) }}.

IoC comportementaux

Au-delà des signatures de fichiers, l'activité des vers se révèle par leur comportement. Par exemple :

  • Des explosions soudaines d'événements de publication npm provenant d'un seul mainteneur.
  • Nouveaux flux de travail qui poussent les données vers des points de terminaison externes.
  • Requêtes POST sortantes déclenchées par les exécuteurs CI.
  • Dépôts publics récemment créés avec des blobs codés.

Chasses rapides

# Find postinstall in package.json
grep -R --line-number '"postinstall"' --include="package.json" /path/to/archives

# Detect tarballs with bundle.js
find /path/to/tarballs -name "*.tgz" -print0 \
 | xargs -0 -n1 -I{} sh -c 'tar -tf "{}" | grep bundle.js && echo "== {}"'

# Search workflows for toJSON(secrets)
grep -R --line-number "toJSON(secrets)" --include="*.yml" .github || true

Conclusion : Leçons tirées de Shai-Hulud

L'espace Attaque de la chaîne d'approvisionnement de Shai-Hulud L'analyse des paquets npm montre la fragilité de la chaîne d'approvisionnement logicielle actuelle. Ce ver a fait plus qu'ajouter du code malveillant. Il a volé des jetons, envoyé des données, puis s'est republié automatiquement. De ce fait, l'attaque s'est propagée en quelques heures au lieu de plusieurs semaines.

Pour les développeurs et les équipes DevOps, les leçons sont claires :

  • Chaque installation exécute du code. Même un package npm commun peut cacher un ver post-installation.
  • Chaque jeton a une grande valeur. Une fois volé, il peut être utilisé pour propager davantage de logiciels malveillants.
  • Chaque pipeline a besoin de contrôles. Sans guardrails En ce qui concerne les dépendances, les flux de travail et les secrets, un compromis peut rapidement affecter la production.

Par conséquent, pour stopper des attaques comme Shai-Hulud, il faut des contrôles automatiques et faciles à appliquer. Les équipes doivent analyser les paquets npm avant les installations, utiliser des builds avec fichiers de verrouillage, détecter les activités de publication anormales et garantir la courte durée de vie des jetons. Ces étapes ne sont plus facultatives. Elles constituent désormais le fondement de la résilience dans les environnements modernes. pipelines.

Chez Xygeni, nous considérons l'attaque de la chaîne d'approvisionnement Shai-Hulud comme un avertissement pour l'ensemble de l'écosystème open source. La solution durable consiste à intégrer la sécurité de la chaîne d'approvisionnement directement dans le processus de développement, au point de départ du code, des paquets npm et pipelines se connecter.

Vous trouverez ci-dessous la liste complète des paquets et versions npm signalés comme compromis dans Shai-Hulud. Utilisez-la pour vérifier vos fichiers de verrouillage, registres et CI. pipelines pour l'exposition.

Liste des paquets compromis

📦 Aperçu des packages npm compromis

Nom du forfait Version Date de publication
moteur-de-règles-json-simplifié0.2.12025-09-14T17:58:51.203Z
pilote d'avion0.8.82025-09-14T18:35:07.600Z
mcp-knowledge-graph1.2.12025-09-14T18:35:09.494Z
chef de l'air0.3.12025-09-14T18:35:09.521Z
porte de saut0.0.22025-09-14T18:35:09.651Z
tvi-cli0.1.52025-09-14T18:35:10.996Z
@thangved/fenêtre-de-rappel1.1.42025-09-14T20:31:38.479Z
@tnf-dev/api1.0.82025-09-14T20:31:39.547Z
@tnf-dev/js1.0.82025-09-14T20:31:41.251Z
@tnf-dev/mui1.0.82025-09-14T20:31:41.259Z
@tnf-dev/core1.0.82025-09-14T20:31:42.728Z
@teselagen/react-table6.10.202025-09-14T20:37:08.597Z
@hestjs/démo0.1.22025-09-14T20:45:52.348Z
@nexe/eslint-config0.1.12025-09-14T20:45:53.625Z
@hestjs/eslint-config0.1.22025-09-14T20:45:55.044Z
@nexe/config-manager0.1.12025-09-14T20:45:55.066Z
@nexe/logger0.1.32025-09-14T20:45:55.170Z
@hestjs/logger0.1.62025-09-14T20:45:55.197Z
@hestjs/validation0.1.62025-09-14T20:45:55.595Z
@hestjs/core0.2.12025-09-14T20:45:55.888Z
➡️ Voir la liste complète des packages compromis
Nom du forfait Version Date de publication
moteur-de-règles-json-simplifié0.2.12025-09-14T17:58:51.203Z
pilote d'avion0.8.82025-09-14T18:35:07.600Z
mcp-knowledge-graph1.2.12025-09-14T18:35:09.494Z
chef de l'air0.3.12025-09-14T18:35:09.521Z
porte de saut0.0.22025-09-14T18:35:09.651Z
tvi-cli0.1.52025-09-14T18:35:10.996Z
@thangved/fenêtre-de-rappel1.1.42025-09-14T20:31:38.479Z
@tnf-dev/api1.0.82025-09-14T20:31:39.547Z
@tnf-dev/js1.0.82025-09-14T20:31:41.251Z
@tnf-dev/mui1.0.82025-09-14T20:31:41.259Z
@tnf-dev/core1.0.82025-09-14T20:31:42.728Z
@teselagen/react-table6.10.202025-09-14T20:37:08.597Z
@hestjs/démo0.1.22025-09-14T20:45:52.348Z
@nexe/eslint-config0.1.12025-09-14T20:45:53.625Z
@hestjs/eslint-config0.1.22025-09-14T20:45:55.044Z
@nexe/config-manager0.1.12025-09-14T20:45:55.066Z
@nexe/logger0.1.32025-09-14T20:45:55.170Z
@hestjs/logger0.1.62025-09-14T20:45:55.197Z
@hestjs/validation0.1.62025-09-14T20:45:55.595Z
@hestjs/core0.2.12025-09-14T20:45:55.888Z
@hestjs/cqrs0.1.62025-09-14T20:45:55.966Z
@hestjs/scalaire0.1.72025-09-14T20:45:56.386Z
téléchargement de fichiers ng27.0.32025-09-15T02:44:29.555Z
gestionnaire de notifications de condensateur0.0.22025-09-15T04:54:48.431Z
condensateur-plugin-vonage1.0.22025-09-15T04:54:48.501Z
condensateur-plugin-healthapp0.0.22025-09-15T04:54:48.704Z
condensateurandroidpermissions0.0.42025-09-15T04:54:48.753Z
kit d'appel VoIP1.0.22025-09-15T04:54:49.223Z
condensateur-plugin-ihealth1.1.82025-09-15T04:55:08.113Z
@art-ws/common2.0.222025-09-15T05:21:15.411Z
@art-ws/config-eslint2.0.42025-09-15T05:21:17.199Z
ngx-ws1.1.52025-09-15T05:21:17.514Z
@art-ws/slf2.0.152025-09-15T05:21:17.524Z
@art-ws/serveur-http2.0.212025-09-15T05:21:17.745Z
pm2-gelf-json1.0.42025-09-15T05:21:18.413Z
@art-ws/di2.0.282025-09-15T05:21:18.488Z
@art-ws/di-node2.0.132025-09-15T05:21:18.849Z
@art-ws/config-ts2.0.72025-09-15T05:21:19.408Z
@art-ws/db-context2.0.212025-09-15T05:21:19.814Z
@art-ws/openapi0.1.92025-09-15T05:21:19.969Z
@art-ws/application-web1.0.32025-09-15T05:21:20.383Z
@art-ws/ssl-info1.0.92025-09-15T05:21:20.927Z
sca-tools-logiciel-outils-d'analyse-de-composition
Priorisez, corrigez et sécurisez vos risques logiciels
Essai gratuit 7 jours
Pas de carte bleue requise

Sécurisez le développement et la livraison de vos logiciels

avec la suite de produits Xygeni