npm lanzó Package Provenance a finales de 2022. Durante dos años, la adopción promedió entre 20 y 50 paquetes por semana. A esto le siguió Trusted Publishing en 2024. Se escribieron artículos en blogs. Se emitieron alertas de la CISA. La gráfica apenas se movió. Finalmente, Trusted Publishing con OIDC estuvo disponible de forma general (Generally Available) en julio de 2025.
Entonces ocurrió el ataque de Shai-Hulud. La adopción semanal se disparó a 430 paquetes. En 18 meses, la adopción acumulada creció 3,4 veces. Todavía nos encontramos cubriendo solo el 25 % del volumen total de descargas; apenas 11 001 de los 51 370 paquetes principales lo han adoptado. Sin embargo, los ataques movieron la aguja mucho más que cualquier iniciativa de la industria de la seguridad.
Estos son los datos.


En qué consiste Trusted Publishing
Trusted Publishing reemplaza los tokens de la API de npm de larga duración por credenciales de corta duración y por ejecución emitidas a través de OpenID Connect. En lugar de almacenar NPM_TOKEN de forma indefinida en los secretos de tu repositorio de GitHub, tu canal de CI obtiene un token que expira en cuestión de minutos. No hay nada que robar. No hay nada que exfiltrar.
La oleada de ataques que lo cambió todo
26 de agosto de 2025: S1ngularity. Unos atacantes explotaron una configuración errónea en las GitHub Actions del monorrepo de Nx para ejecutar código desde una bifurcación (fork) maliciosa en el contexto de confianza del repositorio principal, robando así el token de publicación de npm. Varias versiones maliciosas de paquetes de Nx estuvieron activas durante cuatro horas, escaneando las máquinas de los desarrolladores en busca de credenciales, claves SSH, monederos de criptomonedas y, de manera notable, buscando activamente herramientas CLI de IA instaladas para ejecutarlas con --dangerously-skip-permissions y extraer el contenido del sistema de archivos. Esa semana, la adopción aumentó de forma notable por primera vez.
8 de septiembre de 2025: Debug/Chalk. Un mantenedor fue víctima de phishing a través de un correo de soporte falso de npm (enviado desde npmjs.help) que recopiló sus credenciales y su código TOTP en tiempo real. 18 paquetes que acumulaban más de 2 000 millones de descargas semanales fueron comprometidos con una carga útil (payload) de robo de criptomonedas que interceptaba silenciosamente las interacciones con monederos del navegador y redirigía los fondos. Las versiones maliciosas estuvieron activas durante dos horas. Esa semana: 103 nuevos paquetes adoptaron Trusted Publishing.
15 de septiembre de 2025: Shai-Hulud oleada 1. Un gusano autorreplicable afectó al ecosistema de npm. Cuando un paquete comprometido encontró tokens adicionales de npm en su entorno, publicó automáticamente versiones maliciosas de todo lo que pudo alcanzar. Resultado: más de 700 paquetes comprometidos, 27 000 repositorios de GitHub maliciosos, 14 000 secretos expuestos en 487 organizaciones. La CISA emitió una alerta el 23 de septiembre. Esa semana: 109 nuevos paquetes.
23 de noviembre de 2025: Shai-Hulud 2.0. Una solicitud de ataque (Pwn Request) contra el repositorio asyncapi/cli exfiltró el token de CI en menos de tres minutos, y luego lo usó para desplegar el gusano a través de una extensión maliciosa de OpenVSX. La campaña se extendió a más de 25 000 repositorios maliciosos. Microsoft publicó directrices el 9 de diciembre. Esa semana: 372 nuevos paquetes. El promedio semanal de los dos años anteriores rondaba los 40.
24 de noviembre de 2025: SHA1-Hulud. Una oleada paralela afectó a Zapier, ENS Domains y otros. Se encontraron credenciales de larga duración almacenadas en repositorios comprometidos. El equipo de seguridad de npm recomendó explícitamente Trusted Publishing como solución. Esa semana: 120 nuevos paquetes.
20 y 21 de marzo de 2026: CanisterWorm. TeamPCP desplegó un gusano de npm mediante tokens robados. Más de 28 paquetes infectados en menos de 60 segundos; la carga útil recopiló credenciales y se autopropagó. Esa semana: 112 nuevos paquetes.
31 de marzo de 2026: Axios. Sapphire Sleet (Corea del Norte) comprometió una cuenta de mantenedor y publicó dos versiones con puertas traseras con 39 minutos de diferencia, cada una inyectando una dependencia falsa que descargaba silenciosamente un troyano de acceso remoto multiplataforma. Los paquetes maliciosos estuvieron activos durante tres horas. Axios cuenta con más de 100 millones de descargas semanales. Esa semana: 138 nuevos paquetes.
8 al 22 de abril de 2026: CanisterSprawl. Un segundo gusano de npm de TeamPCP que utilizaba un nuevo contenedor (canister) ICP. Cuando se descubrieron tokens de PyPI en entornos infectados, saltó de ecosistema mediante inyección .pth. Esa semana: 163 nuevos paquetes.
29 y 30 de abril de 2026: Mini Shai-Hulud I. TeamPCP pasó del robo de tokens al robo de credenciales de CI. Un ataque multi ecosistema afectó a npm, PyPI y Packagist en 24 horas a través de tokens de CircleCI comprometidos. Esa semana: 121 nuevos paquetes.
7 al 11 de mayo de 2026: Mini Shai-Hulud II / TanStack. Aquí está la escalada que lo cambia todo: no robaron un token. TeamPCP utilizó una solicitud de ataque (Pwn Request) para envenenar la caché de GitHub Actions y luego esperó a que se ejecutara el flujo de trabajo de publicación legítimo. Cuando lo hizo —con permisos de id-token: write—, el código controlado por el atacante procedente de la caché envenenada extrajo el token OIDC de la memoria del ejecutor (runner) y lo canjeó a través del propio punto de conexión de tokens de npm. Los paquetes publicados incluían atestaciones de procedencia válidas de SLSA Build Level 3. Trusted Publishing no se eludió; se utilizó como vector de ataque. Más de 170 paquetes en npm y PyPI en 5 horas.
18 y 19 de mayo de 2026: Mini Shai-Hulud III / Nx & AntV. La extensión Nx Console para VS Code fue comprometida utilizando credenciales robadas durante el ataque a TanStack (con cinco días de tiempo de permanencia antes de su uso). Se envenenaron 639 versiones de @antv en npm mediante una cuenta de mantenedor robada, instalando cada una una puerta trasera persistente de tipo kitty-monitor. Esa semana: 144 nuevos paquetes. La semana siguiente: 430. Un récord histórico.
1 al 7 de junio de 2026: Miasma / Hades. La clase de ataque volvió a cambiar. La oleada 1 publicó 90 versiones maliciosas de npm dirigidas a paquetes de Red Hat Cloud Services, no mediante el robo de tokens OIDC, sino abusando directamente del punto de conexión de publicación OIDC. La oleada 2 añadió una técnica binding.gyp para eludir la detección de scripts de instalación. En la oleada 4 (Hades), la campaña había cruzado a PyPI mediante la ejecución de inicio .pth, envenenando 37 wheels en 19 paquetes. Red Hat emitió el boletín RHSB-2026-006. Esa semana: 209 nuevos paquetes.
El patrón y cómo escaló
Los primeros ataques siguieron un guion conocido: hacer phishing a un mantenedor, robar un token de larga duración, publicar malware y propagarse a todo lo que el token pueda alcanzar. Debug/Chalk fue un ataque de phishing. Axios fue una cuenta de mantenedor comprometida.
Sin embargo, los ataques más sofisticados fueron directamente a por la canalización (pipeline) de CI. Tanto S1ngularity como Shai-Hulud 2.0 utilizaron solicitudes de ataque (Pwn Requests), pull requests maliciosos que explotaban flujos de trabajo vulnerables de GitHub Actions de tipo pull_request_target para ejecutar código malicioso dentro del contexto de confianza del repositorio ascendente (upstream). No necesitaban robar un token almacenado; solo necesitaban que el ejecutor (runner) de CI tuviera uno.
Mini Shai-Hulud II fue el punto final lógico de una progresión. Una vez que controlas el ejecutor, puedes extraer cualquier credencial ambiental presente, incluidos los tokens OIDC de corta duración. Los paquetes publicados parecían legítimos en todas las comprobaciones automatizadas: procedencia válida, identidad de mantenedor real y firma correcta. El ataque había evolucionado desde la explotación de secretos almacenados hasta la explotación del propio proceso de compilación.
Miasma escaló aún más. Ni siquiera necesitaba extraer un token: abusó directamente del punto de conexión de publicación OIDC. Cada oleada introdujo una nueva técnica para eludir la detección. Los análisis posteriores (postmortems) seguían señalando los mismos fallos, mientras que los ataques encontraban continuamente nuevas formas de sortear las soluciones recomendadas.
La superficie de ataque es ahora significativamente menor que hace 18 meses. No porque la industria de la seguridad haya convencido a la gente, sino porque los paquetes sufrieron ataques de puerta trasera y los mantenedores terminaron cambiando su configuración.
Esto no es una victoria para la educación en seguridad, sino un dato sobre cómo se toman realmente las decisiones de seguridad en la práctica.
¿Quién era?
Durante la campaña de Shai-Hulud 2.0, el atacante cambió el nombre de su cuenta de GitHub a UnknownWonderer1, casi con seguridad una referencia a los errantes zensunni de Dune: los nómadas perseguidos que se convirtieron en los Fremen, la única cultura que aprendió a vivir en armonía con Shai-Hulud. Este nombre no es obra de alguien que llegó por casualidad al ecosistema, sino de alguien que llevaba tiempo reflexionando sobre él.
El diseño del malware refuerza esa lectura. S1ngularity no se limitó a exfiltrar credenciales discretamente; inyectó un comando de apagado en el perfil del shell, algo que detendría visiblemente la máquina la próxima vez que se abriera una terminal. Ese no es el comportamiento de alguien que intenta pasar desapercibido. Cada campaña se detuvo mucho antes de lo que podría haber hecho. Un gusano que se autopropaga a más de 700 paquetes pero limita su carga útil está tomando una decisión deliberada.
También entendieron la estructura de incentivos mejor que el propio ecosistema. Rara vez se le paga a los mantenedores para asegurar los paquetes. El radio de impacto de una brecha recae sobre los usuarios finales, no sobre la persona que dejó el token en la CI. Las plataformas con el poder de exigir publicaciones seguras son las que menos sufren cuando algo sale mal. Es un clásico fallo de acción colectiva; y que haya 40 000 paquetes desprotegidos después de tres años de avisos es exactamente lo que produce esa estructura. Este atacante comprendió por qué nada se movía y decidió aplicar otro tipo de presión.
Disparos de advertencia
Escribí sobre esto en su momento: los nombres, la moderación en el diseño del malware y la forma en que los ataques se detenían sistemáticamente antes de alcanzar una explotación total. Mi lectura es que Shai-Hulud no era principalmente una operación criminal. Era un mensaje de alguien que conocía el ecosistema lo suficiente como para saber exactamente qué puntos de presión lo harían reaccionar.
Los Fremen rezan para que el paso del Creador purifique el mundo. El atacante parece haber llegado a una conclusión similar: solo un dolor visible obligaría al ecosistema a afrontar aquello que hizo posible el gusano. Para los Fremen, Shai-Hulud no es simplemente un animal destructivo, es el Creador. Su paso arrasa el desierto, pero también purifica e impone las leyes por las que debe regirse todo en ese ecosistema.
No se limitaron a lanzar Shai-Hulud.
Eligieron interpretar al Errante que entendía por qué tenía que llegar.
Por qué seguimos sin solucionarlo
Se lanzó la advertencia, pero el ecosistema no se movió con la suficiente rapidez. El manual de código abierto de Shai-Hulud fue adoptado entonces por actores sin ningún interés en enviar mensajes —TeamPCP, Sapphire Sleet y otros— que fueron directamente a por el robo de credenciales, carteras de criptomonedas y acceso remoto. Frameworks como Mastra se convirtieron en víctimas. El gusano que comenzó como una demostración se transformó en una plantilla.
Lo frustrante es que el freno no responde a una dificultad técnica. La publicación de confianza (Trusted Publishing) es gratuita y lleva diez minutos. El obstáculo es que el coste de no hacerlo aún no ha recaído sobre la persona adecuada. Los mantenedores asumen el riesgo reputacional si su paquete se ve comprometido, pero el daño real recae en los equipos que aguas abajo no escribieron ni una sola línea del paquete afectado. Esa desalineación es estructural. Los ataques disparan temporalmente la adopción, luego la urgencia se desvanece y el siguiente grupo de paquetes vuelve a recurrir por defecto a los tokens de larga duración.
Observa el gráfico. Los picos son reales, al igual que el descenso entre ellos.
Además, Mini Shai-Hulud introdujo un nuevo matiz: incluso los paquetes que adoptaron la publicación de confianza pueden verse comprometidos si la canalización de CI subyacente no está endurecida. Extraer un token OIDC de la memoria del ejecutor es más difícil que robar un secreto almacenado, pero no es imposible, y el ataque cuenta ya con una prueba de concepto pública. La publicación de confianza elimina un vector de ataque, pero no todos.
La brecha de responsabilidad y qué hacer al respecto
Axios tenía más de 100 millones de descargas semanales y no había adoptado la publicación de confianza antes de que Corea del Norte lo vulnerara. Cualquiera podría haber enviado una solicitud de extracción (PR) un año antes, pero nadie lo hizo.
Ese es el déficit de responsabilidad. La comunidad de seguridad publica avisos, redacta análisis posteriores a incidentes y espera a que se produzca el siguiente ataque para mover ficha. Existe una versión más constructiva de esa misma presión: ir a por los 40 000 paquetes que aún no han hecho la transición, al igual que hizo Let's Encrypt con HTTP. Enviar PRs. Abrir incidencias. Señalar los paquetes con un alto volumen de descargas que siguen utilizando tokens de larga duración. Lograr que el coste social de no adoptar Trusted Publishing sea mayor que los diez minutos que lleva solucionarlo.
Este es el tipo de activismo que el ecosistema realmente necesita. No otro aviso de CISA. No otra entrada de blog que se lee y se olvida. Una presión específica, dirigida e incómoda sobre mantenedores concretos de paquetes concretos: aquellos con más de 10 millones de descargas semanales que están a solo una credencial vulnerada mediante phishing de convertirse en el próximo incidente.
La industria de la seguridad lleva tres años sabiendo cuál es la solución. La cuestión es si estamos dispuestos a conseguir que sea socialmente inaceptable ignorarla.
40 000 de los 51 000 paquetes principales aún no han hecho la transición
11 001 paquetes han adoptado Trusted Publishing. Esos 11 000 representan aproximadamente el 25 % del volumen total de descargas, ya que algunos de los paquetes más grandes hicieron el cambio tras cada oleada de ataques. Sin embargo, esto deja a 40 369 paquetes (el 75 % del volumen de descargas) publicando todavía con tokens de larga duración.
Si mantienes un paquete de npm, hazlo ahora mismo. La documentación está aquí. Cuatro líneas de YAML y una casilla de verificación. A continuación, asegúrate de que tus flujos de trabajo de GitHub Actions no utilicen pull_request_target sin límites de confianza explícitos; ese es el vector que utilizó Mini Shai-Hulud para extraer el token OIDC incluso después de que Trusted Publishing estuviera implementado.
Si dependes de paquetes que no han hecho la transición, abre una incidencia o una PR. Es posible que el mantenedor no sepa que Trusted Publishing existe, o que simplemente necesite que alguien logre que no hacer nada resulte más incómodo que aplicar la solución de diez minutos.
El gusano de arena de Dune se llama Shai-Hulud, que significa «el viejo abuelo del desierto». Los Fremen no lo celebran cuando destruye algo; entienden que su paso da forma al ecosistema de maneras que ninguna otra cosa puede.
Esa es la verdad incómoda en el centro de esta publicación. Los ataques funcionaron. El dolor movió ficha de formas que tres años de avisos no pudieron conseguir.
Hemos aprendido la lección. El ecosistema se mueve bajo presión, y esta no tiene por qué venir de un gusano informático. El Viajero entendía por qué tenía que aparecer el Creador. Nosotros estamos trabajando para que la próxima vez no sea necesario.
Más información sobre esto muy pronto.