Ataque masivo a NPM: qué pasó, cómo afecta y cómo protegerse

Ataque masivo a NPM: qué pasó, cómo afecta y cómo protegerse

Noticias, Tecnología

La seguridad de millones de desarrolladores y usuarios se vio comprometida tras un ataque a gran escala contra NPM, la popular plataforma de paquetes de código abierto. En septiembre de 2025, ciberdelincuentes lograron tomar el control de cuentas de mantenedores de paquetes NPM muy utilizados, inyectando código malicioso en actualizaciones de librerías ampliamente usadas. Este incidente ha sido catalogado como uno de los mayores ataques a la cadena de suministro de software en la historia de la comunidad JavaScript.

¿Qué es NPM y qué lenguajes lo usan?

NPM (Node Package Manager) es el gestor de paquetes predeterminado para el ecosistema de JavaScript. Es una herramienta que utilizan principalmente los desarrolladores de Node.js y aplicaciones web para administrar fácilmente las librerías o “dependencias” de sus proyectos. En otras palabras, NPM funciona como una enorme biblioteca o almacén de código reusable: ofrece acceso a un vasto repositorio con más de un millón de módulos de código abierto que cualquiera puede instalar con simples comandos. Esto permite que los programadores compartan y reutilicen código, ahorrando tiempo al no tener que reinventar la rueda para tareas comunes.

NPM soporta principalmente proyectos escritos en JavaScript (y su superset TypeScript), ya que viene incluido con Node.js y es parte integral del desarrollo web moderno. Gracias a NPM, frameworks populares de JavaScript como React, Angular o Vue, así como herramientas de servidor en Node.js, pueden integrar miles de paquetes creados por la comunidad. La razón por la que tantos proyectos usan NPM es porque facilita la instalación, actualización y gestión de dependencias de forma centralizada, asegurando que cada proyecto tenga las librerías correctas en la versión adecuada. De hecho, NPM es el registro de software más grande del mundo en cuanto a cantidad de paquetes disponibles. En resumen, prácticamente cualquier aplicación web o móvil moderna que use JavaScript probablemente dependa de paquetes instalados vía NPM, lo que explica por qué un ataque a NPM puede tener un impacto tan amplio.

¿Cómo se descubrió el ataque y cuál fue el problema?

El ataque se descubrió a principios de septiembre de 2025, cuando expertos en seguridad detectaron que se habían publicado versiones sospechosas de ciertos paquetes muy populares de NPM. Todo comenzó cuando un actor malicioso logró comprometer la cuenta de un mantenedor reconocido de NPM. En particular, el desarrollador Josh Junon (conocido en NPM como “qix”) fue víctima de una campaña de phishing altamente sofisticada. Este mantenedor recibió un correo electrónico que parecía venir del equipo oficial de NPM, usando un dominio falso casi idéntico (npmjs.help). En el mensaje se le amenazaba con bloquear su cuenta si no “actualizaba” urgentemente la configuración de autenticación de dos factores (2FA). Lamentablemente, al hacer clic en el enlace y proporcionar sus datos, el atacante obtuvo el usuario, la contraseña y el código 2FA de una sola vez, tomando control total de la cuenta.

Una vez dentro de la cuenta del mantenedor, el atacante publicó nuevas versiones maliciosas de al menos 18 paquetes muy utilizados, incluyendo librerías famosas como debug y chalk. Estas librerías por sí solas acumulan cientos de millones de descargas cada semana (por ejemplo, debug tiene ~357 millones semanales y chalk casi 300 millones). Sumando todos los paquetes afectados (como ansi-styles, color-convert, strip-ansi, entre otros), superaban los 2 mil millones de descargas por semana – lo que da una idea del alcance de la intrusión. En efecto, se trató de un ataque masivo: al comprometer la cuenta de un solo desarrollador influyente, los atacantes lograron infiltrar malware en decenas de miles de proyectos río abajo que dependían de esas librerías sin saberlo.

La comunidad detectó algo extraño rápidamente. En cuestión de horas, desarrolladores y empresas de seguridad notaron que el código de estas nuevas versiones contenía lógica ofuscada (escondida) sospechosa, específicamente fragmentos de código que no pertenecían a las versiones legítimas. Alrededor de las 9 AM (EST) del 8 de septiembre ya se habían publicado los paquetes infectados, y antes del mediodía ese mismo día el incidente fue expuesto públicamente y el propio mantenedor confirmó la brecha. Inmediatamente se iniciaron acciones de mitigación: se publicaron actualizaciones “limpias” de los paquetes para reemplazar a las comprometidas y NPM retiró las versiones maliciosas en pocas horas. Además, NPM procedió a bloquear o “congelar” las cuentas afectadas para investigar y evitar más daños. En total, las versiones infectadas estuvieron disponibles alrededor de dos horas antes de ser eliminadas. Sin embargo, ese breve lapso fue suficiente para que muchas aplicaciones automáticamente las descargaran (por ejemplo, mediante dependencias que se actualizan en procesos de construcción CI/CD), propagando el malware con una rapidez alarmante.

¿Qué hace el malware y cuáles son las consecuencias para los usuarios?

Candado físico colocado sobre una computadora portátil con código en la pantalla, representando seguridad informática y protección de datos

El código malicioso introducido en estos paquetes estaba diseñado con un objetivo principal: robar criptomonedas y datos sensibles de las aplicaciones que usaran las librerías comprometidas. A diferencia de un virus tradicional, este malware no infecta el sistema operativo ni se instala como un programa independiente; más bien, actúa como una especie de “polizón” dentro de aplicaciones web. Cuando un desarrollador actualizó (sin saberlo) una de estas dependencias comprometidas y luego su proyecto fue desplegado en la web, el código malicioso se integraba al JavaScript de la aplicación. Así, cualquier usuario final que cargaba esa aplicación en su navegador podía estar ejecutando también el malware en segundo plano.

En términos más sencillos, el ataque funcionó así: el malware se infiltra en el navegador web del usuario a través del sitio o aplicación afectada, y allí comienza a vigilar ciertas operaciones financieras. Por ejemplo, intercepta llamadas a APIs de criptomonedas y funciones de red como fetch o XMLHttpRequest (usadas para comunicar con servidores). También engancha las interfaces de wallets (billeteras digitales) en el navegador, como window.ethereum que usan herramientas tipo MetaMask. El malware está constantemente escaneando si el usuario va a realizar una transacción de criptomoneda (ya sea enviar fondos o aprobar un movimiento en Ethereum, Bitcoin, Solana, Tron, Litecoin, etc). En el momento en que detecta una transacción, astutamente reemplaza la dirección de destino legítima por una perteneciente a los atacantes. Esto lo hace de forma silenciosa y cuidada: utiliza técnicas para que la dirección modificada se parezca a la original (cambiando algunos caracteres por otros similares) de modo que a simple vista en la interfaz nada parezca raro. Así, cuando la persona afectada confirma la transacción pensando que todo está correcto, en realidad está enviando dinero al monedero del hacker sin darse cuenta.

Las consecuencias directas de este ataque pueden ser muy graves para los usuarios finales y las empresas: desde pérdida de fondos en criptomonedas (imagine que transfiere dinero a los atacantes sin saberlo), hasta potencial filtrado de datos sensibles. Afortunadamente, hasta donde se ha reportado, el impacto efectivo en robo de criptodivisas fue limitado – al parecer los atacantes no lograron hacer mucho botín antes de ser descubiertos. Sin embargo, el daño potencial fue enorme, y solo la rápida respuesta evitó un desastre mayor. Además, aunque no todos los proyectos afectados eran aplicaciones financieras, el incidente causó una especie de “denegación de servicio” a la industria en el sentido de que miles de desarrolladores tuvieron que pausar su trabajo para revisar si sus aplicaciones estaban comprometidas, actualizar dependencias y reforzar medidas de seguridad. En otras palabras, incluso donde no hubo robo directo, sí hubo pérdidas de tiempo, confianza y productividad.

Para la comunidad de desarrolladores, este ataque fue un balde de agua fría. Demostró lo vulnerable que puede ser la cadena de suministro de software: si un solo mantenedor es engañado, el efecto dominó puede impactar a miles de proyectos y millones de usuarios. Muchos desarrolladores, incluso juniors o personas no técnicas, se preguntan cómo es posible que algo así ocurra y qué se puede hacer al respecto. A continuación, veremos cómo respondió la comunidad y qué medidas se están tomando.

¿Qué hizo la comunidad al respecto?

La respuesta de la comunidad y de los administradores de NPM fue rápida y contundente. Una vez identificado el problema, como mencionamos, se eliminaron las versiones maliciosas y se restauró la seguridad de los paquetes afectados en cuestión de horas. El mantenedor comprometido (Josh “qix” Junon) comunicó abiertamente lo ocurrido, admitiendo que fue víctima del phishing, lo cual sirvió de alerta para otros desarrolladores sobre este tipo de trampas. NPM, por su parte, bloqueó las cuentas involucradas y muy probablemente contactó a los demás propietarios de paquetes populares para reforzar sus medidas de seguridad.

Este incidente también aceleró conversaciones en la comunidad sobre mejorar la seguridad del ecosistema open-source. Ya antes NPM (que es administrado por GitHub/Microsoft) había comenzado a exigir autenticación de dos factores obligatoria para los mantenedores de paquetes críticos. Tras el ataque, se reiteró la importancia de que todos los autores de paquetes tengan 2FA habilitado, para que incluso si una contraseña se ve comprometida, los atacantes no puedan acceder tan fácilmente. Sin embargo, como vimos, el phishing logró saltarse incluso la 2FA al engañar al usuario para que revelara su código temporal. Por ello, algunos expertos sugieren implementar métodos más robustos, como llaves de seguridad física o sistemas de firma digital de paquetes, que hagan más difícil suplantar la identidad de un mantenedor legítimo.

La comunidad de código abierto también está discutiendo la necesidad de herramientas automatizadas de detección de malware en paquetes. Empresas de seguridad como Aikido, Wiz, JFrog, Sonatype, entre otras, han desarrollado sistemas de monitoreo que analizan las nuevas versiones publicadas en NPM en busca de comportamientos sospechosos. De hecho, en este caso varios de esos sistemas alertaron casi de inmediato cuando se publicó el código malicioso, lo que permitió contener el incidente rápidamente. Es posible que en el futuro cercano veamos integradas en NPM algunas de estas medidas, de modo que cuando alguien intente publicar una versión de un paquete que contenga código potencialmente malicioso, se emitan alertas o bloqueos preventivos antes de que llegue a los usuarios.

Otro aspecto que la comunidad ha enfatizado es la educación y concienciación. Muchos desarrolladores están compartiendo sus experiencias sobre cómo identificar correos de phishing como el que engañó al mantenedor. NPM y organizaciones afines podrían enviar recordatorios más visibles sobre nunca hacer clic en enlaces sospechosos y verificar dos veces los dominios de los correos (por ejemplo, notar que npmjs.help no es el dominio oficial npmjs.com). También se está recomendando revisar los logs de proyectos para ver si entre las dependencias instaladas en ese periodo de tiempo entró alguna versión comprometida, y si es así, volver a instalar una versión segura inmediatamente.

En resumen, la comunidad reaccionó con rapidez reparando el daño, y ahora se centra en aprender de lo ocurrido para fortalecer la seguridad a futuro. Esto incluye desde medidas técnicas (2FA, firmas digitales, escáneres de malware) hasta buenas prácticas humanas (desconfiar de correos inesperados, revisar las dependencias antes de actualizar, etc.).

¿Qué puedes hacer para evitar este tipo de ataques en tus dependencias de NPM?

Si bien es difícil para un desarrollador individual anticipar un ataque de esta naturaleza, sí hay buenas prácticas que puedes adoptar para minimizar los riesgos en tus proyectos:

  • Mantén tus dependencias actualizadas, pero con precaución: Actualizar regularmente ayuda a obtener parches de seguridad, pero hazlo de forma informada. Lee las notas de versión y presta atención a alertas de la comunidad. Si se reporta que cierta versión fue comprometida, evita instalarla. Herramientas como npm audit o servicios de monitoreo de vulnerabilidades pueden ayudarte a enterarte de problemas conocidos rápidamente.
  • Habilita la autenticación de dos factores (2FA) en tu cuenta de NPM si eres un mantenedor de paquetes. Esto añade una capa extra de seguridad para que nadie más pueda publicar versiones en tu nombre sin ese código adicional. Y nunca compartas ni ingreses tu código 2FA en sitios que no sean los oficiales; NPM nunca te pedirá que “revalides” tu 2FA por correo de esa manera.
  • Revisa las fuentes de tus paquetes: Mientras sea posible, intenta usar paquetes populares y mantenidos por comunidades confiables. Evita descargar dependencias de fuentes desconocidas o fuera del registro oficial de NPM. Si usas un paquete poco común, considera mirar su código fuente o los comentarios de otros usuarios para asegurarte de que no haya comportamientos extraños.
  • Monitorea tus aplicaciones en producción: Si tu aplicación maneja transacciones (por ejemplo, comercio electrónico o integra criptomonedas), implementa monitoreos que detecten actividades inusuales. En este ataque, por ejemplo, si de repente varias transacciones iban a la misma dirección desconocida, podría saltar una alarma. Revisar los logs y tener alertas de movimientos sospechosos de fondos es recomendable.
  • Sigue las recomendaciones de seguridad de la comunidad: Mantente informado con blogs de seguridad, foros de desarrolladores y las comunicaciones oficiales de NPM/GitHub. Cuando ocurren incidentes como este, suelen publicarse guías de cómo mitigar el problema (por ejemplo, qué versiones específicas actualizar). Participar en la conversación te ayudará a reaccionar rápido si algo afecta a tus proyectos.

Para quienes no programan, puede sonar alarmante que un componente invisible en el código de una aplicación pueda comprometer la seguridad de tantos usuarios. Sin embargo, la comunidad está trabajando activamente para reforzar la cadena de suministro del software y prevenir futuros incidentes.