Ir al contenido principal
Cerrar
Seguridad

Ataque npm: 631 versiones maliciosas en 22 minutos

Gabriel Ferraresi· CEO | Tech86August 2, 20265 min
seguridadnpmsupply-chainteampcpaccount-takeovergithub-actionsclaude-codeexfiltracionslsaprovenance

22 minutos. Entre las 01:44 y las 02:06 UTC del 19 de mayo de 2026, alguien publicó 631 versiones maliciosas en 314 paquetes npm. El vector fue el account takeover de la cuenta npm atool, que mantenía 547 paquetes. Los paquetes tenían 16 millones de descargas semanales agregadas, y echarts-for-react solo tenía 3,8 millones por mes. Analizamos el ataque y la señal es clara: cuando la supply chain se vuelve vector, el tiempo de respuesta de la defensa necesita ser menor que el tiempo del ataque.

La escala: 22 minutos, 631 versiones, 314 paquetes

Los números asustan por la densidad temporal. En 22 minutos, se publicaron 631 versiones maliciosas en 314 paquetes npm. El atacante publicó dentro de los paquetes legítimos, con versiones incrementadas automáticamente, no creó paquetes nuevos, infectó los existentes.

La cuenta atool mantenía 547 paquetes. Los paquetes afectados sumaban 16 millones de descargas semanales agregadas. echarts-for-react solo tenía 3,8 millones de descargas por mes. Cada versión publicada inyectaba un hook preinstall que ejecutaba un script Bun ofuscado de 498KB. Bun en lugar de Node fue una elección deliberada para evadir escáneres basados en Node.js.

La recolección: 20 categorías de credenciales en un solo script

El script Bun recolectaba 20 categorías de credenciales: AWS keys, GitHub PATs, npm tokens, GCP, Azure, Kubernetes, SSH keys, Docker auth, cadenas de conexión de base de datos, Stripe keys, Slack tokens. La exfiltración usaba la GitHub API como dead-drop, las credenciales se commiteaban en repositorios atacantes con nombres de Dune, como harkonnen-melange-742.

La elección de Bun no es accidental. Los escáneres tradicionales de supply chain están calibrados para Node.js. Un runtime diferente evade las firmas conocidas, las heurísticas de AST y los patrones de comportamiento. Cuando la defensa asume Node, el atacante usa Bun.

La persistencia: inyección de workflow, hooks de IA y dead-man switch

Después de la recolección venía la persistencia. Inyección de workflow en GitHub Actions: un workflow llamado "Run Copilot" que volcaba todos los secrets vía toJSON(secrets). Hooks en agentes de IA: .claude/settings.json con un hook SessionStart ejecutando node .claude/setup.mjs. Cada vez que un dev abría una sesión de Claude Code, el malware se reejecutaba.

Había además un daemon del sistema llamado kitty-monitor. Y un dead-man switch: si la víctima revocaba el token de GitHub robado, el daemon ejecutaba rm -rf ~/. No es solo exfiltración, es represalia. El atacante transforma la defensa en el gatillo de destrucción.

La atribución: TeamPCP, UNC6780 y el linaje Shai-Hulud

El ataque fue atribuido a TeamPCP, rastreado como UNC6780 por el Google Threat Intelligence Group. Al día siguiente, según GitHub, la brecha fue confirmada: 3.800 repositorios privados exfiltrados, incluyendo github-mcp-server y github-oauth-proxy. TeamPCP ofreció los repositorios robados por 50.000 dólares, no era rescate, era venta. Según OpenAI, dos dispositivos corporativos fueron comprometidos.

Este es el punto más reciente de un linaje que comenzó en septiembre de 2025. Shai-Hulud original: 500 paquetes, gusano autorreplicante. Después 2.0: 796 paquetes. Después SANDWORM_MODE. Después Bitwarden CLI. Después TanStack. Después @antv. En olas anteriores, el mismo grupo falsificó provenance SLSA Build Level 3 válida, y paquetes maliciosos pasaron la verificación criptográfica. El caso fue catalogado como CVE-2026-45321, CVSS 9.6.

La provenance prueba dónde se construyó. Falta probar si es seguro.

El ecosistema: 454.600 paquetes maliciosos en 2025, 1,8 millones a mediados de 2026

Según datos de ecosistema, 454.600 paquetes maliciosos nuevos en 2025. 1,8 millones acumulados a mediados de 2026. 96,6% en npm. La escala no es de ataques puntuales, es de operación industrializada.

Según npm, la versión 12 lanzada en julio de 2026 desactivó los install scripts por defecto y pasó a exigir staged publishing con aprobación humana y 2FA. Esto ayuda contra los hooks preinstall, pero no resuelve el account takeover ni los hooks en agentes de IA. La defensa necesita ir más allá del registry.

Los controles de Tech86 para supply chain con agentes de IA

Cuando Tech86 implementa controles de supply chain para clientes que usan agentes de IA, el principio base es directo. Ningún package.json ni lockfile modificado por un agente de IA entra sin merge gate humano. Sandbox sin credenciales persistidas. Egress allowlist. Hooks de PreToolUse que exigen --ignore-scripts.

No es paranoia. Es lo mínimo frente a un atacante que planta hooks en .claude/settings.json y hace inyección de workflow en GitHub Actions. La superficie de ataque ahora incluye la configuración del propio agente de IA.

Conclusión: el tiempo de respuesta de la defensa necesita ser menor que el tiempo del ataque

22 minutos de publishing. 24 horas después, GitHub confirmó la brecha. El tiempo de respuesta de tu defensa necesita ser menor que el tiempo del ataque.

Lo repetimos: la provenance prueba dónde se construyó, no si es seguro. Los install scripts desactivados por defecto ayudan, pero no resuelven el account takeover. La defensa real es merge gate humano para cambios de agentes de IA, sandbox sin credenciales persistidas, egress allowlist y hooks PreToolUse que exijan --ignore-scripts. En Tech86 ayudamos a empresas a implementar exactamente esos controles, antes de que lleguen los 22 minutos del próximo ataque.

¿Necesitas orientación especializada?

Agenda una consultoría con nuestros especialistas.

Seguridad de supply chain para CI/CD y agentes de IA

Preguntas Frecuentes

Entre las 01:44 y las 02:06 UTC del 19 de mayo de 2026, en 22 minutos, alguien publicó 631 versiones maliciosas en 314 paquetes npm. El vector fue el account takeover de la cuenta npm atool, que mantenía 547 paquetes. Los paquetes sumaban 16 millones de descargas semanales agregadas, y echarts-for-react solo tenía 3,8 millones por mes. Cada versión inyectaba un hook preinstall que ejecutaba un script Bun ofuscado de 498KB, una elección deliberada para evadir escáneres basados en Node.js. El ataque fue atribuido a TeamPCP, rastreado como UNC6780 por el Google Threat Intelligence Group.

El ataque plantó .claude/settings.json con un hook SessionStart que ejecutaba node .claude/setup.mjs. Cada vez que un dev abría una sesión de Claude Code, el malware se reejecutaba. La persistencia también incluía inyección de workflow en GitHub Actions, un workflow llamado Run Copilot que volcaba todos los secrets vía toJSON(secrets), y un daemon del sistema llamado kitty-monitor. Había además un dead-man switch: si la víctima revocaba el token de GitHub robado, el daemon ejecutaba rm -rf ~/.

La provenance prueba dónde se construyó. Falta probar si es seguro. En olas anteriores, el mismo grupo falsificó provenance SLSA Build Level 3 válida, y paquetes maliciosos pasaron la verificación criptográfica. El caso fue catalogado como CVE-2026-45321, CVSS 9.6. La provenance atestigua la cadena de build, pero no atestigua la intención del código. Un paquete construido en un pipeline legítimo, con provenance válida, todavía puede contener un hook preinstall malicioso si el maintainer fue comprometido.

Según datos de ecosistema, 454.600 paquetes maliciosos nuevos en 2025 y 1,8 millones acumulados a mediados de 2026, de los cuales 96,6% en npm. El linaje atribuido al mismo grupo comenzó en septiembre de 2025: Shai-Hulud original (500 paquetes, gusano autorreplicante), después 2.0 (796 paquetes), después SANDWORM_MODE, después Bitwarden CLI, después TanStack, después @antv. El ataque de mayo de 2026 es el punto más reciente de ese linaje.

Según npm, la versión 12 lanzada en julio de 2026 desactivó los install scripts por defecto y pasó a exigir staged publishing con aprobación humana y 2FA. Esto reduce el riesgo de hooks preinstall, pero no resuelve el account takeover ni los hooks en agentes de IA. La defensa completa exige merge gate humano para cambios hechos por agentes de IA, sandbox sin credenciales persistidas, egress allowlist y hooks PreToolUse que exijan --ignore-scripts.

Blog, Contáctanos

¿Tienes alguna pregunta sobre nuestros artículos o servicios? Nuestro equipo está listo para ayudarte.

Agendar Reunión

Reserva un horario.

Agendar Ahora

Correo Electrónico

Envía un mensaje.

[email protected]

WhatsApp

Conversación rápida.

Dirección

Avenida Paulista, 1636 - São Paulo - SP - 01310-200

Especialista Tech86

En línea ahora

¡Hola! ¿Cómo podemos ayudar a escalar tu negocio hoy?

Tech86 Engineering

Valoramos tu privacidad

Utilizamos cookies y tecnologías similares para optimizar tu experiencia, analizar el tráfico del sitio web y personalizar contenido. Al hacer clic en "Aceptar Todos", aceptas el uso de todas las cookies. Lee nuestra Política de Privacidad.