TL; DR
El 14 de setembre de 2025, els investigadors van identificar Shai-Hulud, un cuc autoreplicant amagat a l'interior paquets npm, convertint una actualització de dependències rutinària en una actualització a gran escala atac a la cadena de subministrament. Vist per primera vegada a @ctrl/tinycolor paquet de Daniel dos Santos Pereira, Shai-Hulud recol·lecta secrets, els exfiltra a través de repositoris i fluxos de treball de GitHub i es torna a publicar a través del registre utilitzant credencials robades. En qüestió de dies, el nombre de paquets infectats va passar de desenes a centenars, confirmant que Shaihulud no és només un altre troià, sinó un cuc dissenyat per propagar-se automàticament per l'ecosistema npm.
Impacte: Qualsevol desenvolupador o executor de CI que instal·li paquets npm públics està en risc.
Accions immediates: bloquejar versions conegudes, canviar a instal·lacions només de fitxer de bloqueig, rotar tokens npm i GitHub, auditar fluxos de treball i monitoritzar els indicadors de compromís (IoC).
Què passa?
L' Atac a la cadena de subministrament de Shai-Hulud en paquets npm és un dels incidents més pertorbadors dels darrers temps. A diferència dels troians aïllats, aquest cuc barreja robatori de credencials, exfiltració automatitzada i autoreplicacióEn conseqüència, el període d'infecció es va reduir de setmanes a només unes hores.
Per als equips de DevOps, la lliçó és clara: si cada instal·lació pot executar codi, cada actualització de dependències és un possible punt de violació.
Possible vector inicial i credencials dirigides
Anàlisi inicial indica que l'atac probablement va començar amb credencials robadesPer exemple, campanyes de phishing que suplanten npm login o les indicacions de MFA poden haver capturat tokens de desenvolupador. Un cop els atacants van obtenir aquest primer punt de suport, el cuc es va estendre integrant-se en paquets npm i robant més secrets de:
- fitxers de configuració de npm M'agrada
.npmrc, sovint contenent tokens de publicació. - Variables del mediambient i configuracions amb els PAT de GitHub i CI/CD secrets.
- Punts finals de metadades del núvol (AWS, GCP, Azure) que donen credencials de curta durada per al moviment lateral.
Per tant, el robatori de credencials es va convertir en la plataforma de llançament. Amb tokens npm vàlids i secrets de GitHub, Shai-Hulud podia autoreplicar-se en múltiples paquets i repositoris sense esforç humà addicional.
Impacte executiu de l'atac a la cadena de subministrament de Shai-Hulud
Shai-Hulud encara està actiu avui dia. Aquest cuc accelera la cronologia de l'impacte. El que abans trigava setmanes amb un troià ara es desenvolupa en hores. Com a resultat, la propagació és més ràpida i més difícil de contenir. Avança per:
- Robar tokens de publicació de npm i secrets de GitHub.
- Republicant-se en altres paquets npm.
- Afegint fluxos de treball d'accions de GitHub maliciosos per a la persistència.
Qui està afectat:
Qualsevol equip que instal·li paquets npm públics queda exposat. A més, els desenvolupadors amb tokens npm o GitHub emmagatzemats a la memòria cau s'enfronten a un alt risc. Els executors de CI que utilitzen secrets d'abast ampli també són vulnerables.
Risc empresarial
L'impacte empresarial creix ràpidament. Els tokens robats poden provocar la presa de control de comptes, el segrest de paquets i fins i tot l'ús indegut del núvol. A més, la persistència en els fluxos de treball de GitHub fa que sigui més difícil de netejar. Per tant,, els equips han de tractar Shai-Hulud com un incident continu, no tancat.
Com funciona l'atac a la cadena de subministrament de Shai-Hulud en paquets npm
Objectius i motius de l'atacant
La campanya s'optimitza per tres coses:
- El primer objectiu és robar credencials a escala des d'ordinadors portàtils de desenvolupadors i executors de CI. Això inclou tokens de publicació npm, tokens de GitHub i credencials al núvol. De fet, múltiples anàlisis confirmen la recol·lecció sistemàtica de secrets, com ara l'execució de TruffleHog i la consulta de punts finals de metadades al núvol.
- El segon objectiu és propagar automàticament abús dels drets de publicació dels mantenidors compromesos. Com a resultat, un punt de suport s'expandeix ràpidament a molts, ja que apareixen noves versions infectades d'altres paquets sense esforç humà addicional.
- El tercer objectiu és persisteixen i s'exfiltren de manera fiable a través de la infraestructura de GitHub. Els atacants creen un repositori públic anomenat "Shai-Hulud" amb una doble base64 dades.json, i a més a més, planten un flux de treball que serialitza ${{ toJSON(secrets) }} i ho publica a un webhook estàtic.
La probable recompensa inclou accés a llarg termini als registres i al codi font, un moviment lateral ràpid cap a comptes al núvol i l'opció de convertir encara més la cadena de subministrament en una arma. Els informes públics mostren que els repositoris privats es van fer públics amb un «-migració» sufix, que augmenta l'exposició i l'impuls de les dades
Dins de la càrrega útil de Shai-Hulud: paquet.js en paquets npm
Shai-Hulud s'envia com a gran, inclòs en Webpack i molt minificat Fitxer JavaScript (paquet.js, uns 3–3.7 MB) que s'executa des d'un postinstal·lació enganxar paquet.jsonEn conseqüència, Cada instal·lació activa la càrrega útil automàticament. Aquest disseny amaga els identificadors, comprimeix el flux de control i empeny tota la lògica en un únic artefacte que s'executa durant la instal·lació. Els analistes confirmen constantment l'agrupació de Webpack, la mida de fitxer inusual i l'execució en temps d'instal·lació.
Trets d'ofuscació i antianàlisi que veureu a les mostres:
- Gràfic de mòduls minificat amb ID de mòdul numèrics, comentaris dispersos i flux de control aplanat. A més, Aquesta estructura fa que la revisió manual sigui extremadament difícil.
- Amagar cadenes mitjançant capes base64 i ajudants de construcció. Per exemple, La codificació i descodificació base64 repetides solen aparèixer al voltant de les rutines d'exfiltració.
- Enviament dinàmic a través de evalpatrons d'estil i cossos de funció generats, permetent així que el codi canviï de comportament en temps d'execució.
- Filtratge del sistema operatiu preferir l'execució de Linux i macOS, especialment en executors de CI i ordinadors portàtils de desenvolupador.
Des d'un punt de vista funcional, el paquet és modular. Els articles descriuen mòduls per al descobriment de sistemes operatius, escanejos de sistemes de fitxers i secrets de Git, accés a l'SDK al núvol, operacions de l'API de GitHub i un motor de propagació que edita altres paquets que posseeix el mantenidor. De fet, StepSecurity i ReversingLabs destaquen una funció que actualitza automàticament els paquets amb el hook maliciós.
Execució en temps d'instal·lació a Shai-Hulud: com els paquets npm activen el cuc
L'atac comença quan node d'execucions postinstal·lació paquet.js. En aquest punt, l'script inicialitza i desempaqueta l'estat de treball a la memòria, preparant l'escenari per al funcionament complet del cuc.
Descobriment i recol·lecció
- La càrrega útil descarrega process.env i escaneja els fitxers locals per buscar secrets d'alta entropia i prefixos de tokens. A més, estén la cobertura executant TruffleHog.
- Consulta els punts finals de metadades del núvol per recopilar credencials de curta durada. Per exemple, trucades a
169.254.169.254a AWS ometadata.google.internalen GCP sovint apareixen en hostes infectats. - Per tant, Qualsevol credencial trobada es pot utilitzar immediatament per publicar nous paquets npm o enviar fluxos de treball de GitHub.
Exfiltració
- El cuc crea un nou repositori de GitHub anomenat Shai-Hulud i escriu una doble codificació en base64
data.jsonamb detalls de la plataforma, abocaments d'entorn i secrets. Com es pot veure, aquest comportament sorollós és fàcil de detectar si els defensors saben on mirar. - També planta un flux de treball d'accions de GitHub, sovint en una branca anomenada shai-hulud, que serialitza
${{ toJSON(secrets) }}i publica les dades a un webhook estàtic. A més, aquest flux de treball persisteix fins que algú l'elimina activament.
Propagació
- Amb qualsevol token npm descobert, la càrrega útil enumera tots els paquets que pertanyen al mantenidor compromès. A continuació, obté cada tarball, injecta bundle.js i una entrada postinstal·lació i torna a publicar el paquet.
- Com a resultat, desenes de paquets infectats poden aparèixer en qüestió d'hores, multiplicant el radi de l'explosió a tot l'ecosistema.
Persistència i exposició
El cuc manté vius els fluxos de treball maliciosos i, en diversos casos, converteix els repositoris privats en públics amb un «-migració» sufix. En conjunt, això garanteix que l'atacant mantingui un punt de suport i maximitzi la fuga de dades.
Nota de detecció clau
Aquest ús inusual de ${{ toJSON(secrets) }} en els fluxos de treball d'Accions és rar. Per tant, els equips ho haurien de tractar com un indicador de senyal alt durant les caceres.
Patró de flux de treball sanejat que hauries de buscar
Aquest ús inusual de a JSON(secrets) en Accions és un indicador de senyal alt en aquest incident.
Pseudocodi de propagació d'alt nivell (segur, descriptiu)
Els analistes van observar aquest bucle a escala, cosa que explica el ràpid salt de desenes a centenars de paquets infectats.
Per què això és un cuc en un ecosistema de paquets
Un cuc és un programari maliciós que es propaga pel seu compte sense requerir passos manuals de l'operador en cada etapa. En els sistemes operatius, els cucs solen explotar vulnerabilitats de la xarxa per moure's d'una màquina a una altra. En canvi, Shai-Hulud opera dins del registre npm. La seva ruta eficient és a través de reutilització de credencials.
El cuc aprofita els tokens de publicació npm robats. Tan bon punt obté credencials vàlides, torna a publicar les versions infectades en altres paquets propietat del mateix mantenidor. Posteriorment, aquests paquets són instal·lats per desenvolupadors o executors de CI desprevinguts, i el cicle es repeteix.
Per aquest motiu, els analistes de seguretat, inclosos Lectura fosca, classifiquen Shai-Hulud com a cuc autoreplicant en lloc d'un simple troià o un incident de typosquatting. La diferència és important: un troià normalment compromet un hoste, però un cuc amplifica el seu impacte automàticament a través d'un ecosistema.
Full de trucs "Com funciona"
Per resumir el cicle de vida de Shai-Hulud, aquí teniu una estafacisdesglossament dels seus passos principals:
- Un paquet amb postinstal·lació està instal·lat, i
bundle.jsexecuta. - La càrrega útil aboca variables d'entorn, escaneja fitxers i l'historial de git, s'executa TruffleHogi consulta els serveis de metadades al núvol. En conseqüència, qualsevol secret trobat esdevé immediatament útil.
- L'exfiltració es produeix de dues maneres: primer, creant un repositori públic anomenat Shai-Hulud amb una doble codificació base64
data.json; en segon lloc, plantant un flux de treball d'accions de GitHub que publiqui${{ toJSON(secrets) }}a un webhook. - Utilitzant qualsevol token npm robat, el cuc torna a publicar tots els altres paquets propietat del mantenidor compromès amb el mateix hook maliciós. D'aquesta manera, la infecció es multiplica ràpidament.
- Finalment, l'atacant té més secrets, més paquets per difondre i persistència dins dels comptes i repositoris de GitHub.
Com evitar aquest tipus d'atac, a la pràctica
Shai-Hulud és una crida d'atenció. Un cuc que roba fitxes i es republica no és un risc futur, sinó que està en directe. ecosistema de paquets npm avui. Per evitar aquest tipus de atac a la cadena de subministrament, els equips necessiten controls que siguin programables, automatitzats i aplicats directament CI/CD pipelines. Aquestes són les mateixes defenses que ja podeu implementar amb Xígeni.
Atura els artefactes dolents a la porta
Hauries d'escanejar els paquets i els fitxers tar de npm abans que arribin als desenvolupadors o a les tasques de CI. bundle.js fitxers, postinstal·lació sospitosa hooksi els marcadors d'ofuscació serveixen com a primers senyals d'alerta. A més, imposar períodes de refredament i versions fixades a pipelines impedeix que es consumeixin automàticament versions noves i no verificades.
Harden CI/CD per defecte
Guardrails in CI/CD són essencials. Rebutgen fusions o instal·lacions que introdueixen nous scripts o binaris. Alhora, bloquegen fluxos de treball que serialitzen secrets o intenten publicacions externes. Els equips també haurien de requerir instal·lacions només de fitxers de bloqueig (npm ci) a tot arreu pipelines perquè els conjunts de dependències romanguin reproduïbles i segurs.
Reduir el radi de l'explosió de la fitxa
Els secrets no s'han de convertir en punts únics de fallada. Analitzeu contínuament el codi, les configuracions i pipeline sortida per credencials exposadesEls tokens s'han de limitar a un àmbit estret, atès que tenen una vida útil curta, i s'han de rotar automàticament quan es detecta una exposició. Per regla general, qualsevol token utilitzat en un amfitrió que hagi executat una postinstal·lació sospitosa s'ha de tractar com a compromès.
Veure el comportament dels cucs aviat
Detecció d’anomalies és clau. Per exemple, els pics sobtats en els esdeveniments de publicació de npm, els nous fluxos de treball que apareixen sense motiu o els repositoris públics nous plens de fitxers codificats estranys poden indicar activitat de cucs. Per tant, els equips haurien d'emetre alertes ràpidament i aïllar qualsevol mantenidor o executor que mostri aquests signes d'advertència.
Corregeix ràpidament sense trencar les compilacions
La velocitat i la seguretat han d'anar juntes. Automatitzat pull requests pot substituir els paquets npm compromesos per versions verificades. A més, accessibilitat i explotabilitat L'anàlisi garanteix que les actualitzacions es mantinguin mínimes i estables. Finalment, reconstrueix els executors de CI afectats a partir d'imatges netes un cop confirmada l'exposició, evitant que l'atac s'estengui més.
Indicadors de compromís (IoC)
Quan analitzen Shai-Hulud, els equips han de tenir en compte tots dos IoC estàtics en fitxers i IoCs comportamentals in pipelines. Junts, aquests senyals ajuden a detectar infeccions precoçment i a respondre abans que el cuc s'estengui més.
IoC estàtics
Les següents coincidències observades en els resums SHA-256 bundle.js mostres:
- 46faab8ab153fae6e80e7cca38eab363075bb524edd79e42269217a083628f09
- 81d2a004a1bca6ef87a1caf7d0e0b355ad1764238e40ff6d1b1cb77ad4f595c3
- dc67467a39b70d1cd4c1f7f7a459b35058163592f4a9e8fb4dffcbba98ef210c
A més, observeu aquests patrons recurrents:
- A
bundle.jsa l'arrel del paquet. "postinstall": "node bundle.js"dinspackage.json.- Repositoris anomenats Shai-Hulud.
- Fluxos de treball de GitHub que contenen
${{ toJSON(secrets) }}.
IoCs comportamentals
Més enllà de les signatures de fitxers, l'activitat dels cucs es revela a través del comportament. Per exemple:
- Ràfegues sobtades d'esdeveniments de publicació de npm per part d'un mantenidor.
- Nous fluxos de treball que envien dades a punts finals externs.
- Sol·licituds POST de sortida activades per executors de CI.
- Repositoris públics creats recentment amb blobs codificats.
Caça ràpida
Conclusió: Lliçons de Shai-Hulud
L' Atac a la cadena de subministrament de Shai-Hulud en paquets npm mostra com de fràgil s'ha tornat la cadena de subministrament de programari actual. Aquest cuc va fer més que afegir codi maliciós. Va robar tokens, va enviar dades i després es va tornar a publicar automàticament. A causa d'això, l'atac es va estendre en hores en lloc de setmanes.
Per als desenvolupadors i els equips de DevOps, les lliçons són clares:
- Cada instal·lació executa codi. Fins i tot un paquet npm comú pot amagar un cuc de postinstal·lació.
- Cada token té un valor alt. Un cop robat, es pot utilitzar per propagar encara més programari maliciós.
- Cada pipeline necessita xecs. Sense guardrails pel que fa a dependències, fluxos de treball i secrets, un compromís pot afectar ràpidament la producció.
Per tant, aturar atacs com el de Shai-Hulud requereix controls automàtics i fàcils d'aplicar. Els equips haurien d'escanejar els paquets npm abans de les instal·lacions, utilitzar compilacions de fitxers de bloqueig, detectar activitats de publicació estranyes i mantenir els tokens de curta durada. Aquests passos ja no són opcionals. En canvi, són la base de la resiliència en els sistemes moderns. pipelines.
A Xygeni, veiem l'atac a la cadena de subministrament de Shai-Hulud com un avís per a tot l'ecosistema de codi obert. El camí sostenible a seguir és incorporar la seguretat de la cadena de subministrament directament al procés de desenvolupament, en el punt on el codi, els paquets npm i... pipelines connecten.
A continuació es mostra la llista completa de paquets i versions de npm que s'han reportat com a compromeses a Shai-Hulud. Feu-la servir per comprovar els vostres fitxers de bloqueig, registres i CI. pipelines per a l'exposició.
Llista de paquets compromesos
📦 Vista prèvia dels paquets npm compromesos
| Nom del paquet | version | Data de publicació |
|---|---|---|
| motor de regles json simplificat | 0.2.1 | 2025-09-14T17:58:51.203Z |
| pilot aeri | 0.8.8 | 2025-09-14T18:35:07.600Z |
| mcp-knowledge-graph | 1.2.1 | 2025-09-14T18:35:09.494Z |
| bufanda d'aire | 0.3.1 | 2025-09-14T18:35:09.521Z |
| porta de salt | 0.0.2 | 2025-09-14T18:35:09.651Z |
| TVI-CLI | 0.1.5 | 2025-09-14T18:35:10.996Z |
| @thangved/finestra-de-retorn-de-crida | 1.1.4 | 2025-09-14T20:31:38.479Z |
| @tnf-dev/api | 1.0.8 | 2025-09-14T20:31:39.547Z |
| @tnf-dev/js | 1.0.8 | 2025-09-14T20:31:41.251Z |
| @tnf-dev/mui | 1.0.8 | 2025-09-14T20:31:41.259Z |
| @tnf-dev/core | 1.0.8 | 2025-09-14T20:31:42.728Z |
| @teselagen/react-table | 6.10.20 | 2025-09-14T20:37:08.597Z |
| @hestjs/demo | 0.1.2 | 2025-09-14T20:45:52.348Z |
| @nexe/eslint-config | 0.1.1 | 2025-09-14T20:45:53.625Z |
| @hestjs/eslint-config | 0.1.2 | 2025-09-14T20:45:55.044Z |
| @nexe/config-manager | 0.1.1 | 2025-09-14T20:45:55.066Z |
| @nexe/logger | 0.1.3 | 2025-09-14T20:45:55.170Z |
| @hestjs/logger | 0.1.6 | 2025-09-14T20:45:55.197Z |
| @hestjs/validació | 0.1.6 | 2025-09-14T20:45:55.595Z |
| @hestjs/core | 0.2.1 | 2025-09-14T20:45:55.888Z |
➡️ Veure la llista completa de paquets compromesos
| Nom del paquet | version | Data de publicació |
|---|---|---|
| motor de regles json simplificat | 0.2.1 | 2025-09-14T17:58:51.203Z |
| pilot aeri | 0.8.8 | 2025-09-14T18:35:07.600Z |
| mcp-knowledge-graph | 1.2.1 | 2025-09-14T18:35:09.494Z |
| bufanda d'aire | 0.3.1 | 2025-09-14T18:35:09.521Z |
| porta de salt | 0.0.2 | 2025-09-14T18:35:09.651Z |
| TVI-CLI | 0.1.5 | 2025-09-14T18:35:10.996Z |
| @thangved/finestra-de-retorn-de-crida | 1.1.4 | 2025-09-14T20:31:38.479Z |
| @tnf-dev/api | 1.0.8 | 2025-09-14T20:31:39.547Z |
| @tnf-dev/js | 1.0.8 | 2025-09-14T20:31:41.251Z |
| @tnf-dev/mui | 1.0.8 | 2025-09-14T20:31:41.259Z |
| @tnf-dev/core | 1.0.8 | 2025-09-14T20:31:42.728Z |
| @teselagen/react-table | 6.10.20 | 2025-09-14T20:37:08.597Z |
| @hestjs/demo | 0.1.2 | 2025-09-14T20:45:52.348Z |
| @nexe/eslint-config | 0.1.1 | 2025-09-14T20:45:53.625Z |
| @hestjs/eslint-config | 0.1.2 | 2025-09-14T20:45:55.044Z |
| @nexe/config-manager | 0.1.1 | 2025-09-14T20:45:55.066Z |
| @nexe/logger | 0.1.3 | 2025-09-14T20:45:55.170Z |
| @hestjs/logger | 0.1.6 | 2025-09-14T20:45:55.197Z |
| @hestjs/validació | 0.1.6 | 2025-09-14T20:45:55.595Z |
| @hestjs/core | 0.2.1 | 2025-09-14T20:45:55.888Z |
| @hestjs/cqrs | 0.1.6 | 2025-09-14T20:45:55.966Z |
| @hestjs/scalar | 0.1.7 | 2025-09-14T20:45:56.386Z |
| càrrega-de-fitxers-ng2 | 7.0.3 | 2025-09-15T02:44:29.555Z |
| gestor de notificacions de condensador | 0.0.2 | 2025-09-15T04:54:48.431Z |
| condensador-connector-vonage | 1.0.2 | 2025-09-15T04:54:48.501Z |
| complement-de-condensador-aplicació-de-salut | 0.0.2 | 2025-09-15T04:54:48.704Z |
| permisos d'android del condensador | 0.0.4 | 2025-09-15T04:54:48.753Z |
| kit de trucades VoIP | 1.0.2 | 2025-09-15T04:54:49.223Z |
| condensador-plugin-ihealth | 1.1.8 | 2025-09-15T04:55:08.113Z |
| @art-ws/common | 2.0.22 | 2025-09-15T05:21:15.411Z |
| @art-ws/config-eslint | 2.0.4 | 2025-09-15T05:21:17.199Z |
| ngx-ws | 1.1.5 | 2025-09-15T05:21:17.514Z |
| @art-ws/slf | 2.0.15 | 2025-09-15T05:21:17.524Z |
| @art-ws/servidor-http | 2.0.21 | 2025-09-15T05:21:17.745Z |
| pm2-gelf-json | 1.0.4 | 2025-09-15T05:21:18.413Z |
| @art-ws/di | 2.0.28 | 2025-09-15T05:21:18.488Z |
| @art-ws/di-node | 2.0.13 | 2025-09-15T05:21:18.849Z |
| @art-ws/config-ts | 2.0.7 | 2025-09-15T05:21:19.408Z |
| @art-ws/db-context | 2.0.21 | 2025-09-15T05:21:19.814Z |
| @art-ws/openapi | 0.1.9 | 2025-09-15T05:21:19.969Z |
| @art-ws/aplicació-web | 1.0.3 | 2025-09-15T05:21:20.383Z |
| @art-ws/ssl-info | 1.0.9 | 2025-09-15T05:21:20.927Z |




