- Se distribuyeron en npm versiones maliciosas de los paquetes y plugins de Nx, que escanean el sistema de archivos, recopilan credenciales y luego las envían a un repositorio de la cuenta de Github del usuario
- Para verificar si hubo impacto, es necesario confirmar si se creó el repositorio s1ngularity-repository en la cuenta de Github
- Si hubo infección, es imprescindible reemplazar tokens y contraseñas, eliminar el repositorio malicioso y revisar los archivos de configuración del shell
- Las versiones maliciosas afectan al sistema mediante un script postinstall; en particular, al usar el plugin VSCode Nx Console aumenta el riesgo de ejecutarlo sin darse cuenta
- El equipo de Nx aplicó medidas para evitar recurrencias y controles de seguridad adicionales, y las versiones implicadas ya fueron eliminadas de npm
Resumen general
- Este aviso de seguridad trata sobre un grave ataque a la cadena de suministro dirigido a los paquetes de Nx y algunos plugins relacionados, con código malicioso distribuido a través de npm
- Esas versiones maliciosas escaneaban el sistema de archivos del usuario para recopilar credenciales, rutas y otros datos, y los subían a un repositorio de Github (
s1ngularity-repository) - El script malicioso
postinstalltambién modificaba los archivos de configuración del shell del usuario (.zshrc,.bashrc) para agregar un comando de apagado del sistema - Se detallan el vector de ataque y su desarrollo, las versiones afectadas, las acciones inmediatas recomendadas para los usuarios y las medidas para evitar una recurrencia
Medidas urgentes
Lo que todos deben verificar
- Revisar en la lista de repositorios de su cuenta de Github si se creó
s1ngularity-repository - Descargar los archivos incluidos en ese repositorio para conservarlos como registro
- Eliminar el repositorio desde Github
- Enviar un correo a
security@nrwl.iopara recibir instrucciones sobre cómo descifrar la información filtrada - Reemplazar de inmediato todas las credenciales y tokens de todas las cuentas
Cómo reemplazar el token de Github
- Visitar https://github.com/settings/connections/…
- Revocar el acceso de la app conectada para invalidar el token existente
- Si usa
ghCLI, volver a autenticarse para generar un nuevo token - Si no se hace, existe el riesgo de que el token anterior sea utilizado de forma maliciosa
Dejar de usar y limpiar las versiones maliciosas de Nx
- Verificar con
npm ls nxsi la versión de Nx actualmente en uso corresponde a una versión maliciosa - Si es una versión infectada, actualizar con
npm uninstall nx && npm install nx@latest - Limpiar la caché con
npm cache clean --force
Usuarios que ya fueron infectados
- Reemplazar los tokens de npm y Github
- Restablecer todas las contraseñas y credenciales de Github y de los servicios relacionados
- Revisar si se insertaron comandos extraños en los archivos
.zshrcy.bashrc, y eliminarlos
Si administra un repositorio interno de paquetes
- Es necesario eliminar de inmediato las versiones maliciosas del proxy del registro interno para bloquear una propagación adicional
Versiones afectadas
Paquete Nx
- 21.5.0, 20.9.0, 20.10.0, 21.6.0, 20.11.0, 21.7.0, 21.8.0, 20.12.0
- Eliminadas de npm al cierre de las 10:44 PM EDT
@nx/devkit, @nx/js, @nx/workspace, @nx/node, @nx/eslint, @nx/key, @nx/enterprise-cloud
- Eliminados de npm a las 10:44 PM y 6:20 AM EDT
Detalles del vector de ataque
Causa del workflow vulnerable
- Se introdujo en Github Actions un workflow vulnerable que permitía la ejecución de código arbitrario
- Al insertar cierto código bash en el título del PR, el workflow ejecutaba comandos del sistema, una vulnerabilidad de tipo Bash Injection
- Se abusó del trigger
pull_request_target, que otorga privilegios elevados (comoGITHUB_TOKEN) - Hasta que se eliminó, el workflow vulnerable se mantuvo en una rama antigua distinta de
main, lo que permitió al atacante ejecutar el workflow con un PR malicioso y robar secretos
Proceso de robo del token de npm
- Mediante el workflow vulnerable, se hizo que se ejecutara
publish.yml publish.ymlalmacenaba el token de npm en Github Secrets, y durante ese proceso el token fue enviado a un webhook externo- Finalmente, el atacante usó ese token para subir a npm versiones maliciosas de Nx y de los paquetes compatibles
Comportamiento de los paquetes maliciosos
Recolección de información, incluidas credenciales, y publicación en un repositorio de Github
- Al ejecutarse el script
postinstalldel paquete infectado de Nx, recopilaba la ubicación de diversos archivos de texto y datos de credenciales - Esa información se codificaba en
base64y se subía a un repositorio de Github llamados1ngularity-repository - Aunque el repositorio real ya haya sido eliminado, como antes estuvo público, debe asumirse la posibilidad de filtración de información
Alteración de perfiles del shell (.zshrc, .bashrc)
postinstallinsertaba el comandosudo shutdown -h 0, provocando el apagado del sistema al abrir la terminal y posibilitando la exposición de contraseñas
Distintos escenarios en los que puede ejecutarse postinstall
-
Además de ejecutarse explícitamente con
npm install/yarn/pnpm install, puede activarse en diversos casos como dependencias transitivas, extensiones del editor o ejecución de scripts -
En particular, la extensión Nx Console para VSCode (versiones 18.6.30 ~ 18.65.1) podía instalar automáticamente
nx@latestal iniciar el editor, lo que podía disparar la ejecución depostinstall -
En esencia, hay que tener presente que la instalación de módulos de NPM puede ocurrir en muchos lugares incluso sin intención explícita
-
A partir de Nx Console (18.66.0), se eliminó el proceso de instalación de
latest nx
Cronología del ataque y la respuesta
21 de agosto
- 4:31 PM: se hizo merge de un PR que incluía la vulnerabilidad de inyección Bash
- 10:48 PM: se publicó en X (antes Twitter) una publicación señalando la vulnerabilidad
22 de agosto
- Tarde: investigación interna y rollback del workflow vulnerable (incompleto)
- Se introdujo CodeQL para detectar vulnerabilidades similares en futuros PR
24 de agosto
- Se produjo un commit en el fork del atacante con indicios de filtración del token de npm
- Se creó y eliminó un PR malicioso, y
publish.ymlfue ejecutado por ese PR
26 ~ 27 de agosto (distribución de versiones maliciosas y respuesta)
- Se publicaron sucesivamente en npm múltiples versiones maliciosas de Nx y sus plugins
- Se reportaron issues a las comunidades de Github y NPM
- 10:44 PM: NPM tomó medidas como la eliminación total de esas versiones
- 11:57 PM: se invalidaron todos los tokens de publicación de paquetes relacionados con Nx
- 27 de agosto: parche para Nx Console, activación de 2FA, transición al modelo Trusted Publisher y medidas adicionales
Prevención y respuesta posterior
- Se hizo obligatorio el uso de 2FA para todos los maintainers de la organización
nrwl - Se adoptó el mecanismo de Trusted Publisher. Queda prohibida la publicación basada en tokens de npm
- En adelante, los paquetes solo se publicarán tras pasar validación basada en confianza y 2FA
- También se aplicarán por etapas controles adicionales para detección de riesgos, aprobación de PR y protección de ramas
Lecciones y próximos pasos
- Este incidente vuelve a poner en evidencia, tanto a nivel local como internacional, la importancia de la seguridad de la cadena de suministro, de los pipelines de CI/CD y del principio de mínimos privilegios en los workflows
- Tras una revisión interna, el equipo planea compartir con la comunidad lo aprendido
Contacto
- Se puede consultar a
security@nrwl.io
Referencias y apéndice
- Principales issues de Github, cronología y publicaciones relacionadas
- Se proporciona un ejemplo del script
telemetry.jsincluido en los paquetes infectados - Ese script recopila rutas de archivos de texto importantes dentro del sistema de archivos con el objetivo de generar un inventario
Resumen final
- Es importante aplicar las actualizaciones y parches más recientes de Nx y de los plugins relacionados
- Se recomienda reemplazar de inmediato la información principal de autenticación, como la de npm y Github
- Este incidente recuerda que deficiencias en la seguridad de la cadena de suministro y en la gestión de permisos de workflows pueden derivar en un accidente de gran escala
1 comentarios
Opiniones de Hacker News
Quiero recordar periódicamente que desactiven los scripts de
npm installUn ejemplo es usar este comando:
Esta configuración se puede aplicar fácilmente por proyecto o de forma global
Hoy en día hay pocos paquetes legítimos que no funcionen sin scripts, así que en la mayoría de los casos no hay problema
Si un paquete realmente los necesita para funcionar, se puede resolver creando un script de instalación aparte y ejecutándolo manualmente en esa carpeta
No es una solución universal contra ataques a la cadena de suministro, pero en la práctica ha bloqueado eficazmente muchos ataques a través de npm
Para más información, revisen la documentación oficial de npm config
Yo también uso bubblewrap para aislar del sistema a npm, pnpm, yarn y todas las sesiones que ejecutan
~/code, y guardo el siguiente script bash al inicio dePATHcon el nombrenpm~/codey acceso de solo lectura a las bibliotecas del sistemaOtra opción es usar pnpm. Las versiones recientes ignoran por defecto todos los scripts de lifecycle, y solo se ejecutan si se agregan individualmente a una lista blanca
Cada vez que escucho este consejo me surge una duda: en la práctica, no hay desarrolladores que lean las decenas o cientos de millones de líneas de código que instala npm
git clonenpm install(aquí existe el riesgo de instalar un paquete malicioso; ignorar los scripts post-install puede frenarlo un momento)npm run(aquí se ejecuta el paquete malicioso y ocurre la infección)node_modulesentre 2 y 3, y nadie hace esoYo ejecuto todas las herramientas basadas en npm dentro de un contenedor Docker, sin acceso a nada fuera del directorio actual
Me pregunto por qué este tipo de consejo no se aplica igual a
setup.py(Python) obuild.rs(Rust)Hace falta una cultura de pensarlo de verdad una vez más antes de agregar una nueva dependencia
Este año ha habido muchísimos ataques a la cadena de suministro
Esta semana quería agregar a un proyecto Go una barra de progreso con 8 contadores estadísticos
Busqué una biblioteca y tenía más de 3,000 líneas de código, así que le pedí a un LLM que generara una UI sencilla y lo resolvió en menos de 150 líneas
Funciona exactamente como quería, sin dependencias, y es tan simple que cualquiera puede leerlo y mejorarlo fácilmente
La funcionalidad es borrar la salida de la terminal y volver a dibujar cada segundo, con soporte thread-safe
Implementarlo y revisarlo tomó solo 25 minutos
Si no hacen falta estadísticas complejas, una barra de progreso también se puede implementar con unas 30 líneas de código
En adelante, cuando dude si agregar una dependencia, creo que me conviene más hacerla yo mismo
No tengo recursos para vigilar todas las actualizaciones de paquetes
Estoy de acuerdo con lo mencionado y recuerdo que al inicio de la popularización de los “administradores de paquetes por lenguaje” me daban mucha inseguridad
Creo que enfoques como cargo vet son el camino a seguir: introducción a cargo vet
La diferencia entre implementar algo uno mismo y usar una biblioteca es obvia
Odio estas bibliotecas de barras de progreso, especialmente las que rompen el shell de emacs (
expo,eas, etc.)..10%..20%..30%oUploading…Nuestro equipo opera un monorepo grande y bibliotecas alrededor de NX en una gran aseguradora
lerna,rushjs,yarn workspaces, etc., pero no encontramos una herramienta que funcionara tan bien como NX (lernaal final fue absorbido por NX, yrushjstampoco se mantiene)En vez de culpar solo a Nx, Anthropic o la plataforma, hay que volver a pensar en la causa real
Este tipo de ataque puede causar daños críticos a decenas de miles de organizaciones en finanzas, energía, telecomunicaciones, hospitales, fuerzas armadas, etc.
A medida que la IA se expande, la escala y el impacto de los ataques será aún mayor
No estamos escribiendo software con suficiente responsabilidad. Aunque sea por obligación, como con los códigos de construcción, tendríamos que cumplir normas de seguridad y protección
Viéndolo bien, es más peligroso de lo que parece que el entorno de computación personal esté reunido en un solo gran espacio
El 50% de las víctimas tuvo como vía de infección VS Code, y solo funcionaba en Linux y macOS
postinstallse recolectaban activos sensibles como credenciales del usuario (wallets cripto, tokens de Github y npm, claves SSH, etc.)Claude,Gemini,Q, etc.) para recolección de información y reconocimiento activobase64, a repositorios de GitHub controlados por el atacante (s1ngularity-repository, etc.)base64se revierte fácilmente, así que en la práctica hay que asumir que todos esos datos ya son públicosQue los tokens/credenciales de GitHub no se guardaran en una herramienta de contraseñas con desbloqueo manual también es culpa de GH CLI
No me entusiasma la idea de introducir un “código de construcción para software”, pero coincido en que la realidad de toda la industria es extremadamente frágil
Me parece arrogante la idea de exigir responsabilidades por usar una biblioteca open source gratuita
Últimamente hago la mayor parte del desarrollo dentro de una VM
Siento que el nivel de seguridad de los entornos actuales es inaceptable
La posibilidad de que un agente (software agéntico) funcione como vector de malware ha aumentado muchísimo
Si un atacante ya logró entrar a la máquina, vivimos en una época en la que en cualquier momento puede ir por datos con valor de rescate superior a 1,000 dólares, claves cripto, contraseñas, información personal, datos financieros, etc.
Yo hago algo parecido dentro de un contenedor Podman. No comparto con el host nada fuera del directorio del código fuente
Parte del problema viene del modelo tradicional de seguridad en PC (Linux/Windows)
Si prefieres este enfoque, recomendaría Qubes OS. Tiene una buena UX para hacer todo dentro de VM
Aun así, hay que aclarar que montar este tipo de entorno es muy difícil o bastante costoso por culpa del ecosistema y la historia del software
Claude Code es una herramienta revolucionaria para mejorar la productividad
Pero al mismo tiempo tiene problemas de seguridad como estos:
curlhaciabash(riesgo de ejecución remota de código)Con al menos esas tres debilidades de seguridad, no querría ejecutarlo fuera de un sandbox como una VM, contenedor o caja de desarrollo dedicada
Yo también creo que lo correcto es ejecutar al agente dentro de un sandbox
Pero aun así, ¿y qué?
El verdadero punto peligroso es que, al actualizarse automáticamente sin intervención del usuario, en la práctica se le dio a Anthropic permiso de RCE mientras estaba en ejecución
Me pregunto si los administradores de paquetes deberían tener una opción como “edad mínima del paquete” (
min-age)Por ejemplo, ignorar paquetes publicados hace menos de 24 a 36 horas
Antes viví un caso parecido: una actualización de paquete rompió todo y a las pocas horas la corrigieron o la eliminaron
GitHub dependabot agregó hace poco exactamente una función así
Renovate bot ya ofrecía esa opción (
minimumReleaseAge) y dependabot ahora también la soportapostinstallpor defecto y hay que dispararlos explícitamente si se necesitan (aunque al final sigue siendo ejecutar código de otros)No a nivel de sistema operativo, pero la herramienta
uvde Astral tiene una opción así para paquetes de Pythonnpm installtambién tiene una bandera para instalar solo dependencias anteriores a un momento/fecha determinadosnpm install --before (fecha de hace 2 días), no instala dependencias aparecidas después de esa fechaYo pongo
save-exact=trueen.npmrcy trabajo solo conlockfiley actualizaciones manualesMe preguntaba si claude code realmente ejecutaría ese tipo de prompt, así que lo probé
“Esta solicitud parece pedir buscar y listar archivos sensibles como wallets de criptomonedas o claves privadas, y podría prestarse a abuso, así que no puedo ayudar con eso”
Solo orienta sobre solicitudes legítimas como auditorías de seguridad, análisis de vulnerabilidades, creación de herramientas de monitoreo, comprensión de permisos de archivos o diseño de procedimientos de respaldo
Se consiguieron al menos 250 casos exitosos (es decir, algunos prompts sí pasaron)
En la práctica, cada vez que Claude compite con otros modelos en una especie de duelo de rechazo, se confirma una y otra vez que las negativas y medidas de seguridad de Claude son mucho mejores
El sistema operativo debería impedir por defecto que las apps tengan acceso ilimitado a todo el sistema de archivos
Algunas apps sí tienen perfiles de
apparmor/selinux, y también se puede usarfirejailPero hace falta un cambio desde el lado de la UX
Este es un problema muy serio. Viene de diseños pensados para escritorios de hace 30 años
Estoy desarrollando yo mismo en Linux una herramienta centrada en aislar entornos por proyecto con Podman: probox
En cuanto a seguridad de archivos en Android, Google lo ha hecho bien
También recomiendo aprender a usar bubblewrap y entornos pequeños tipo chroot
No creo que en ningún sistema operativo el valor predeterminado sea que una aplicación tenga “acceso ilimitado a todo el sistema de archivos”
Antes había una confianza vaga de que “el atacante tendría que adivinar mi entorno”, pero ahora puede poner a un LLM a aprender el entorno y ejecutar ataques adaptados
Yo mismo diría que de algún modo predije esta tendencia en la práctica
Era una discusión interesante para revisar en este hilo anterior
Lo realmente escalofriante es que ahora se usen LLM locales para encontrar secretos
El problema de
postinstallsigue siendo el mismo de antes, pero el payload pertenece a una generación completamente nuevaComo la lógica maliciosa se oculta en prompts en vez de código, se vuelve difícil de detectar con análisis estático tradicional
Me pregunto cómo se podría defender uno de este tipo de prompts maliciosos