Distribuyen masivamente paquetes maliciosos en NPM descargados más de 86 mil veces
(arstechnica.com)- Se confirmó que en el repositorio de NPM se subieron más de 100 paquetes maliciosos para robar credenciales sin ser detectados desde agosto, y que en conjunto fueron descargados más de 86 mil veces
- La empresa de seguridad Koi informó que una campaña de ataque llamada PhantomRaven distribuyó 126 paquetes maliciosos aprovechando la función Remote Dynamic Dependencies (RDD) de NPM
- RDD es una estructura que permite que un paquete descargue dinámicamente código de dependencias desde dominios no confiables, por lo que no es detectada por herramientas de análisis estático
- Los atacantes aprovecharon esta función para descargar código malicioso mediante conexiones HTTP y, en los metadatos del paquete, aparecía como “0 Dependencies”, por lo que ni los desarrolladores ni los escáneres de seguridad lo detectaban
- Esta vulnerabilidad estructural expone los límites de la gestión de seguridad del ecosistema de NPM y los riesgos del mecanismo de instalación automática
Expansión de paquetes maliciosos en el repositorio de NPM
- Los atacantes aprovecharon una debilidad estructural del repositorio de código de NPM para subir, desde agosto, más de 100 paquetes para robar credenciales
- La mayoría de los paquetes se distribuyó sin ser detectada, y el total acumulado de descargas superó las 86,000
- La empresa de seguridad Koi nombró este ataque como la campaña PhantomRaven y analizó que se explotó una función específica de NPM
- Según Koi, de los 126 paquetes maliciosos, alrededor de 80 seguían todavía en NPM al momento de redactarse el artículo
Estructura vulnerable de Remote Dynamic Dependencies (RDD)
- RDD es una función que permite que un paquete descargue dinámicamente código de dependencias desde sitios web externos
- Normalmente las dependencias se descargan desde la infraestructura confiable de NPM, pero RDD también permite descargas mediante conexiones no cifradas como HTTP
- Los atacantes de PhantomRaven configuraron esta función para descargar código desde una URL maliciosa, por ejemplo
http://packages.storeartifact.com/npm/unused-imports- Estas dependencias no son visibles para los desarrolladores ni para los escáneres de seguridad, y en la información del paquete aparecen como “0 Dependencies”
- Debido a la función de instalación automática de NPM, este código de dependencia “invisible” se ejecuta automáticamente
Límites de detección de las herramientas de seguridad
- Oren Yomtov, de Koi, señaló que “PhantomRaven es un caso que explota con precisión un punto ciego de las herramientas de seguridad existentes”
- RDD no es detectado por herramientas de análisis estático
- Por esto, los atacantes pudieron evadir las verificaciones de seguridad y distribuir código malicioso
Factores adicionales de vulnerabilidad
- Koi explicó que las dependencias descargadas mediante RDD se vuelven a descargar desde el servidor del atacante en cada instalación
- Como no hay caché ni control de versiones, incluso el mismo paquete podría inyectar código malicioso distinto según el momento de instalación
- Esta estructura de descarga dinámica dificulta la verificación de integridad de los paquetes
Estructura y contexto de NPM
- NPM es un administrador de paquetes para JavaScript gestionado por npm, Inc., una subsidiaria de GitHub
- Es el administrador de paquetes predeterminado de Node.js y está compuesto por un cliente de línea de comandos y el npm registry
- En el registry se almacenan paquetes públicos y privados de pago, y pueden buscarse a través del sitio web
- Este incidente se señala como un caso que muestra cómo la estructura de gestión automática de dependencias de NPM puede ser explotada en ataques
Otras menciones
- Al final del artículo se menciona la opinión de que debería bloquearse la ejecución innecesaria de JavaScript
- Sin embargo, se señala que en este ataque incluso código JavaScript esencial fue utilizado de forma maliciosa
2 comentarios
Creé un script de escaneo en tiempo real.
En la ruta del repositorio sospechoso,
npx sha1-hulud-scannersolo tienes que ingresarlo.
Código fuente: https://github.com/developerjhp/sha1-hulud-scanner
Opiniones en Hacker News
Últimamente tengo un alias para ejecutar el comando
npmdentro de un contenedor DockerAsí no expone mis variables de entorno, no accede a archivos fuera del directorio actual y tampoco puede acceder a archivos de configuración como
.bashrcReferencia: Run tools inside Docker
npmdescarga código arbitrario que se va a ejecutar de inmediatoEn su lugar recomiendo
pnpm. Por defecto no ejecuta scripts de lifecycle y permite definir en una lista blanca cuáles scripts se autorizanSi de verdad quieres protección, no solo la instalación sino toda la ejecución debería ir dentro de un sandbox
Bloquear solo el post-install, como ahora, no es más que una medida a medias. Los ataques a la cadena de suministro son cada vez más peligrosos
Si
neovimovscodequedan comprometidos, ya pueden hacer cosas bastante peligrosas con los permisos del usuarioUn alias simple sirve para
node/npm, pero es difícil aplicarlo a otros programas, porque hay que montar en el contenedor los recursos que necesitanSiempre me he preguntado por qué la gente ejecuta
npmen su sistema con tanta naturalidadDesde la perspectiva de alguien acostumbrado a builds reproducibles como
make, me impactó quenpmdescargue cosas distintas cada vez y produzca resultados distintosIncluso me parecía raro amarrar la generación de CSS a dependencias de npm. Por eso intenté congelar todo el entorno de npm dentro de Docker, pero al final parece una batalla perdida
maven,nuget,pip,npm, todos son igualesSi siguiéramos dependiendo de los package managers de las distribuciones como antes, sería imposible tener un ecosistema tan rápido como el actual
Aun así, están apareciendo nuevos package managers con más seguridad. No está bien criticar el medio sin entender la razón de fondo
npmcon Docker, me pregunto si validabas ese entorno cada vez que actualizabas dependenciasEn realidad
npmypnpmya fijan las dependencias por defecto con archivos locknpm install thing” es demasiado fácil y baratoMucho open source termina lleno de código para el currículum más que por calidad, y al final se usa para hacer cosas como rastreadores publicitarios de grandes empresas o apps de billetera
npm installno solo descarga paquetes, también ejecuta códigoDe hecho corre los hooks preinstall, install y postinstall del
package.json¿Cuál sería una razón legítima para necesitar ejecutar comandos arbitrarios durante la instalación?
Informe relacionado: PhantomRaven npm malware
Otro caso: Blog de Socket.dev
Por ejemplo, los paquetes del kernel de Linux ejecutan scripts post-install para regenerar initramfs y actualizar GRUB
La mayoría de los paquetes DEB/RPM incluyen scripts así. O sea, es un problema de diseño en sí
npmcualquiera puede subir un paqueteLas distribuciones Linux tienen un sistema confiable de maintainers y hasta construyen directamente una raíz de confianza basada en PGP
En cambio,
npm,pip,rubygems,cargoy otros son básicamente una versión refinada de “curl | bash”Ese tipo de build post-install fue necesario para reducir la carga de mantenimiento
Package.swiftPero tengo entendido que está fuertemente sandboxeado, así que es difícil abusar de eso
Referencia: Documentación de SwiftPM, PackageDescription
pnpm v10desactiva por defecto todos los scripts de lifecycle y el usuario tiene que permitirlos manualmenteDiscusión relacionada
Viendo los ataques recientes a
npm, ya me pregunto si desarrollar connpmsigue siendo seguroCada vez que empiezo un proyecto en React se instalan cientos de paquetes y ni sé qué hacen
En backend se instalan explícitamente solo los paquetes necesarios, pero el frontend parece una caja de Pandora de vulnerabilidades
npmes el más grande y por eso sale más en las noticiasjjde Rust y metió 470 paquetes;wan2gpde Python, 211. Al final todos están más o menos igualComo en el caso de
xz, cada dependencia queda en manos de personas aleatorias, y hay que confiar en que no caerán en ataques de ingeniería socialPyPItampoco es seguro. Incluso hubo casos en que se inyectó código malicioso en paquetes legítimos mediante el hackeo de GitHub ActionsCada vez que desarrollo con frameworks como Angular o Vue me da ansiedad
Ver miles de dependencias dentro de
node_modulesse siente como el anuncio de un desastreSi hacen phishing a un solo desarrollador de open source, todo podría infectarse de inmediato
El ecosistema de JavaScript está roto de raíz. Un simple typo basta para quedar expuesto a un ataque a la cadena de suministro
Con NuGet o Maven también puede pasar, pero allá la biblioteca estándar es más grande, hay menos dependencias y se siente que tienes más control
No es perfecto, pero al menos es un paso adelante
De esas 86,000 descargas, es muy probable que la mayoría no hayan sido usuarios reales sino scanners automatizados o bots
Cuando subes una versión nueva, a veces se descarga cientos de veces en uno o dos días, pero puede que no sea gente real
O sea, quizás casi no hubo usuarios infectados
También hay muchos ataques dirigidos a nombres de paquetes inventados por alucinaciones de chatbots de IA. Es más que una simple estadística
Para una explicación más detallada del ataque, ver el artículo de BleepingComputer
Me pregunto si habrá alguna forma de detectar o filtrar durante
npm installlos paquetes que usan URLs HTTP como dependenciaComo pueden enviar payloads distintos según quién haga la solicitud, los scanners comunes lo tienen difícil para detectarlos
Como desarrollador aficionado, me pregunto cómo debería prepararme ante este tipo de ataques a la cadena de suministro
Cuando sigues tutoriales conocidos e instalas dependencias, sin darte cuenta te vuelves descuidado con la seguridad
También corro varios servicios en mi homelab, y me preocupa que algún bot llegue a infiltrarse. ¿Por dónde debería empezar?
No es una garantía perfecta, pero es mucho mejor que dejar que comprometan todo el servidor
Copiar y usar directamente solo el código necesario también puede ser una buena forma de aprender y una opción más segura
Con una estructura así, no hace falta que millones de usuarios verifiquen todo por su cuenta: la confiabilidad se asegura a nivel de distribución
Ejemplos: Hono, Zod
Últimamente me cambié a Bun, que ya trae integrados cosas como drivers de DB o clientes S3, así que hay menos descargas adicionales
La estructura de traer dependencias desde hooks de lifecycle puede convertirse en un punto de giro del ataque en cualquier momento
Aunque ahora sea legítimo, más adelante el dueño puede ser hackeado o cambiar de idea y convertirlo en código malicioso
Este tipo de hooks de instalación son, al final, un diseño insostenible