El ataque a TanStack que comprometió 169 paquetes npm sin robar una sola contraseña
El 14 de mayo de 2026, en menos de seis minutos, más de 100 paquetes npm que acumulan más de 50 millones de descargas semanales fueron comprometidos en uno de los ataques de cadena de suministro más sofisticados que ha visto el ecosistema JavaScript. Lo más perturbador no fue la escala — fue el método. No hubo phishing, no se filtraron contraseñas, no se robaron tokens de forma directa. El atacante usó la propia infraestructura de confianza de GitHub y npm en su contra.
Este incidente, conocido informalmente como el ataque "Shai-Hulud" o "prairie dog" por la forma en que el malware apareció y desapareció rápidamente antes de propagarse, afectó directamente a TanStack — una de las librerías más populares del ecosistema React — y desde ahí se extendió a organizaciones como Mistral AI, UiPath, OpenSearch y Guardrails AI. Si tu equipo usa npm y no revisa activamente la configuración de sus pipelines de CI/CD, este artículo es para ti.
Vamos a desmenuzar exactamente cómo funcionó el ataque, por qué las medidas de seguridad existentes no lo detuvieron, y qué puedes hacer hoy para reducir tu exposición.
Cómo funciona el Trusted Publishing de npm (y por qué no fue suficiente)
Para entender el ataque, primero hay que entender qué es el Trusted Publishing de npm. Esta funcionalidad, recomendada por npm desde hace casi dos años, elimina la necesidad de almacenar tokens de publicación como secretos estáticos en los repositorios. En cambio, cuando un workflow de GitHub Actions necesita publicar un paquete, GitHub firma criptográficamente una declaración indicando qué workflow se está ejecutando, en qué repositorio y en qué rama. npm verifica esa firma contra una lista de permisos configurada por la organización, y solo entrega un token temporal si todo coincide. Ese token vive unos pocos minutos en la caché del servidor de CI y luego expira.
En teoría, esto hace que los ataques de phishing tradicionales sean inútiles — no hay token permanente que robar. En la práctica, el atacante encontró una forma de obtener ese token temporal sin necesidad de robarlo directamente: simplemente lo hizo generarse en el momento equivocado, en un contexto que él controlaba.
La vulnerabilidad: pull_request_target y la caché compartida de CI
El punto de entrada fue una decisión de configuración en el workflow de GitHub Actions de TanStack. El equipo había configurado el trigger del workflow usando pull_request_target, una opción que tiene un comportamiento importante y peligroso: cualquier pull request entrante — incluso uno creado desde un fork externo — se ejecuta con los permisos del repositorio principal, no del fork.
El atacante aprovechó esto de la siguiente manera. Hizo un fork del repositorio de TanStack, creó un pull request desde ese fork y lo cerró inmediatamente. El PR nunca fue revisado por ningún mantenedor. Pero el simple acto de crearlo fue suficiente para disparar el workflow de publicación, porque pull_request_target no distingue entre PRs legítimos y PRs de forks maliciosos cuando se trata de permisos.
Con esos permisos activos, el código del atacante escribió un archivo envenenado en la caché compartida del servidor de CI — la misma caché que GitHub Actions usa para reutilizar dependencias entre jobs y acelerar los builds. Unas horas después, cuando un PR legítimo fue mergeado al repositorio principal, el workflow de publicación se ejecutó de nuevo. Esta vez, el archivo envenenado en la caché se activó, capturó el token de publicación de npm del entorno de CI, y lo usó para publicar 84 nuevas versiones comprometidas de paquetes de TanStack.
Lo más ingenioso — y aterrador — de este vector de ataque es que no dejó rastros obvios en el flujo normal de trabajo. El PR malicioso fue cerrado antes de que alguien lo viera. La caché envenenada esperó pacientemente. Y el token fue usado en el contexto de un workflow legítimo, lo que hace que los logs se vean completamente normales.
La propagación: de TanStack a 169 paquetes en pocas horas
Una vez que los paquetes de TanStack estaban comprometidos, el malware pasó a su segunda fase: propagarse. Cuando un desarrollador ejecutaba npm install e instalaba uno de los paquetes infectados, el malware escaneaba el sistema en busca de tokens de publicación de npm almacenados localmente. Si encontraba alguno, los usaba para publicar nuevas versiones envenenadas de los paquetes que ese desarrollador mantenía, replicando el mismo patrón.
Así fue como el problema de TanStack se convirtió en un problema de toda la industria. La primera ola de víctimas incluyó mantenedores en Mistral AI, UiPath, OpenSearch, Guardrails AI y Squawk. A través de sus SDKs de Python, el gusano saltó también al registro de PyPI. Para la mañana siguiente, la firma de seguridad Aikido estaba rastreando 373 versiones comprometidas en 169 paquetes.
El malware también mostró una sofisticación preocupante en su capacidad de persistencia. Se incrustó directamente en VS Code y en Claude Code — el agente de programación de Anthropic. Esto significaba que aunque un desarrollador desinstalara los paquetes maliciosos, el gusano se volvía a ejecutar la próxima vez que abría su editor. Adicionalmente, instaló un proceso en segundo plano que verificaba cada 60 segundos si el token de GitHub robado seguía siendo válido. En el momento en que el token expiraba, activaba lo que el investigador describió como "modo crimen de guerra": eliminaba el directorio raíz del sistema infectado.
Como capa adicional de camuflaje, el malware comenzó a falsificar commits firmados por la aplicación GitHub de Claude Code, mezclando su actividad maliciosa con los commits generados por IA que los mantenedores ya estaban acostumbrados a ver en sus repositorios.
¿Cómo aplica esto en tu empresa?
Si tu equipo de desarrollo usa npm y tiene pipelines de CI/CD en GitHub Actions — y en 2026 la mayoría los tiene — este ataque es directamente relevante para ti. Hay tres acciones concretas que puedes implementar hoy.
La primera y más impactante es migrar a PNPM 11 o superior. Esta versión viene con tres funciones habilitadas por defecto que habrían bloqueado este ataque para la mayoría de los afectados. Minimum release age rechaza cualquier paquete publicado hace menos de 24 horas — una ventana de tiempo que supera con creces el periodo en que la mayoría de los paquetes maliciosos son detectados y retirados del registro. Block exotic subdependencies bloquea cualquier dependencia transitiva que no provenga del registro oficial de npm, cerrando uno de los vectores más usados para introducir malware de forma silenciosa. Y approved builds bloquea por defecto todos los scripts de instalación automática, permitiéndote revisar y aprobar manualmente solo los paquetes que realmente necesitan ejecutar código durante la instalación.
La segunda acción es auditar tus workflows de GitHub Actions específicamente en busca del trigger pull_request_target. Si lo encuentras, evalúa si realmente necesitas que PRs de forks externos tengan acceso a los permisos del repositorio principal. En la mayoría de los casos, la respuesta es no. Cambiar a pull_request (sin el sufijo _target) ejecuta el código del fork en un entorno aislado con permisos mínimos.
La tercera es revisar la configuración de caché compartida en tus pipelines. La caché de GitHub Actions es conveniente para acelerar builds, pero si diferentes jobs comparten caché sin restricciones, un job con permisos bajos puede contaminar el entorno de un job con permisos altos. Considera usar claves de caché específicas por contexto y revisa qué jobs tienen acceso de escritura a la caché compartida.
Para empresas en Perú y Latinoamérica que están escalando sus equipos de desarrollo o que tienen productos en producción con dependencias de npm, este tipo de ataque es especialmente relevante porque el tiempo de respuesta ante incidentes de seguridad suele ser más largo que en mercados con equipos de seguridad dedicados. Implementar barreras preventivas como las de PNPM 11 es mucho más económico que responder a una brecha activa.
Conclusión
El ataque a TanStack de mayo de 2026 es un recordatorio de que la seguridad en la cadena de suministro de software no es un problema teórico. Es un vector de ataque activo, sofisticado y en constante evolución. Las medidas de seguridad que npm implementó con Trusted Publishing eran buenas — pero el atacante encontró una forma de rodearlas usando la propia infraestructura de GitHub en su contra.
La buena noticia es que las herramientas para reducir significativamente tu exposición ya existen y están disponibles hoy. PNPM 11, una revisión cuidadosa de los triggers de tus workflows y una política clara sobre scripts de instalación pueden marcar la diferencia entre ser una víctima más y no serlo.
En Consultoría-Ti trabajamos con equipos de desarrollo en Perú y Latinoamérica que están construyendo productos reales con estas tecnologías. Si quieres revisar la configuración de seguridad de tu pipeline de CI/CD o necesitas apoyo para implementar estas prácticas en tu equipo, conversemos. Un pipeline seguro no es un lujo — es parte del costo real de tener software en producción.
Fuentes y Referencias
Fireship — Shai-Hulud just prairie dogged the NPM registry (YouTube)
✨ Contenido generado con ContentFlow — Consultoría-Ti