Volver al blog
Análisis de incidentes

ChainDrop: el gusano de npm que se publicó a sí mismo

Equipo de Plaza Cyber Security4 de agosto de 20265 min readIncidente: 4 de agosto de 2026
Un puerto de contenedores de noche, con grúas y buques iluminados sobre el agua oscura

La mayoría de los ataques a la cadena de suministro necesita que una persona cometa un error. Este necesitó que una persona cometiera un error una vez, y después siguió solo.

Qué pasó

El 4 de agosto de 2026, unos atacantes obtuvieron las credenciales del mantenedor de keyv y cacheable, paquetes npm pequeños y poco vistosos que sostienen buena parte del JavaScript que existe. Solo la familia keyv acumula bastante más de mil millones de descargas mensuales.

Lo que publicaron no fue simplemente una versión con puerta trasera. Fue un gusano.

El paquete malicioso traía un hook preinstall, una función legítima de npm que ejecuta comandos antes de instalar el paquete. Ese hook soltaba un runtime de Bun y ejecutaba una carga ofuscada que rastreaba la máquina en busca de credenciales: tokens de npm y GitHub, llaves de AWS, GCP, Azure y Alibaba Cloud, cuentas de servicio de Kubernetes, llaves SSH, tokens de Vault y claves de API de servicios de IA. Los investigadores contaron más de 300 patrones de credencial en el cosechador. El botín se comprimía, se cifraba y salía.

Después venía lo que lo convirtió en gusano. Donde encontraba un token de npm con permisos de publicación que no exigiera autenticación de dos factores, enumeraba todos los paquetes a los que esa cuenta podía escribir e infectaba cada uno. Otros desarrolladores instalaban esos paquetes, en otras máquinas, con otros tokens.

En unas cuatro horas, la campaña había publicado más de 2,200 versiones maliciosas en más de 400 paquetes distintos. Entre las organizaciones alcanzadas aparecen Deliveroo, Picsart, Qlik y ServiceTitan. El malware desciende de la familia Shai-Hulud; más allá de eso, la atribución sigue sin confirmarse, y ahí la dejamos.

UNA CUENTA DE MANTENEDOR, CUATRO HORAS09:001paquete+1h~50paquetes+2h~200paquetes+4h452paquetesTOKEN npm ROBADO · SE PUBLICA DE NUEVO2,251 VERSIONES · ~2 MIL MILLONES DE DESCARGAS/MES
El gusano usó cada juego de credenciales npm robadas para publicarse en todos los paquetes a los que esa cuenta podía escribir. El crecimiento es compuesto, no lineal.

Tres cosas que explota, y ninguna es un error de programación

npm install ejecuta código. Los hooks de instalación existen por razones legítimas: compilar módulos nativos, preparar un paquete después de descargarlo. Pero la consecuencia es que agregar una dependencia ejecuta código arbitrario en la máquina que instala, antes de que nadie haya revisado una sola línea. Cada npm install es un acto de confianza, y casi todos se hacen sin pensarlo así.

Tu servidor de compilación es el objetivo más rico que tienes. Los desarrolladores piensan en sus laptops. Los atacantes piensan en CI. Un agente de compilación guarda credenciales de despliegue, llaves de nube, tokens de registro y material de firma, todo en variables de entorno y todo accesible para cualquier proceso que la compilación lance. Una laptop da el acceso de una persona; un servidor de compilación da el de la organización.

Los tokens de publicación sin MFA convierten un compromiso en muchos. La propagación del gusano dependía por completo de encontrar tokens capaces de publicar sin un segundo factor. Donde los mantenedores tenían 2FA obligatorio para publicar, la cadena se cortaba.

Esto no es solo un problema de desarrollo

Es tentador archivarlo como "algo del equipo de ingeniería". Es un error, por dos razones.

Primero, casi toda organización hoy produce software de algún tipo, aunque sea un sitio web, una herramienta interna o unos scripts de automatización. Si algo en tu negocio ejecuta npm install, pip install o composer install dentro de un pipeline automatizado, tienes esta exposición.

Segundo, las credenciales que este gusano buscaba no son credenciales de desarrollo. Son llaves de nube de producción, acceso a Kubernetes y tokens de gestores de secretos. Un compromiso que empieza en un pipeline de compilación termina en la infraestructura que opera el negocio. El radio de impacto lo define hasta dónde llega el servidor de compilación, no en qué estaba trabajando la persona que desarrolla.

Qué hacer en concreto

Fija tus dependencias y versiona el lockfile. Un lockfile hace que una compilación instale exactamente las versiones que probaste, y no lo más nuevo que hubiera a las 09:00 UTC el día de un ataque. Las organizaciones que peor la pasan en campañas rápidas son las que resuelven versiones de cero en cada compilación.

Desactiva los scripts de instalación donde puedas. npm ci --ignore-scripts evita el hook preinstall que transportó esta carga. Algunos paquetes sí necesitan sus scripts; permítelos en una lista explícita en vez de habilitarlos todos por defecto.

Trata el servidor de compilación como producción. Credenciales de vida corta en lugar de llaves permanentes, acotadas exactamente a lo que el pipeline necesita. Nada de llaves de administrador de nube compartidas en las variables de CI. Ejecutores separados para trabajo confiable y no confiable.

Exige MFA para publicar lo que distribuyes. Si tu organización mantiene paquetes públicos o internos, este es el control que rompe la cadena de propagación.

Conoce de qué dependes. Un inventario de componentes de software suena burocrático hasta que un aviso nombra 400 paquetes y necesitas saber en una hora si alguno es tuyo. La pregunta "¿nos afecta?" debería tomar minutos, no días.

Rota ante la sospecha, no ante la confirmación. Si un paquete comprometido llegó a una máquina con credenciales, asume que esas credenciales salieron. Rotar es barato; una investigación que intente probar una negativa no lo es.

El resumen

ChainDrop no rompió npm. Usó npm tal como está diseñado —hooks de instalación, tokens de publicación, dependencias transitivas— y ese diseño asume que las cuentas de los mantenedores no están comprometidas. Una lo estuvo, y el resto fue aritmética.

La postura defensiva no es dejar de usar código abierto, lo que no es posible ni sensato. Es aceptar que tu árbol de dependencias es superficie de ataque que no escribiste, mantener cortas y acotadas las credenciales que viven cerca de él, y poder responder rápido cuando aparezca el aviso.

Fuentes

#supply chain#npm#ci-cd#credentials#incident analysis