17 puntos por GN⁺ 2025-11-25 | 5 comentarios | Compartir por WhatsApp
  • En el registro de NPM, más de 1,000 componentes fueron infectados en cuestión de horas con el mismo método, y se distribuyeron nuevas versiones que incluían código malicioso
  • Los paquetes maliciosos se hacían pasar por un script de instalación del runtime Bun, agregando setup_bun.js y bun_environment.js ofuscado; al ejecutarse, usaban TruffleHog para robar credenciales locales
  • La información sensible recopilada, como tokens de AWS/GCP/Azure, GitHub y NPM, era enviada al exterior mediante un runner de GitHub Actions llamado SHA1HULUD
  • El script malicioso ejecutaba automáticamente npm publish para realizar una autorreplicación tipo gusano, lo que terminó infectando más de 27,000 repositorios de GitHub
  • Se considera otro caso que vuelve a poner en evidencia la amenaza a la seguridad de la cadena de suministro en todo el ecosistema open source

Resumen del ataque

  • El 24 de noviembre de 2025, HelixGuard detectó que más de 1,000 paquetes del registro de NPM fueron infectados en pocas horas con la misma técnica
    • Las nuevas versiones fingían agregar el runtime Bun e incluían el script preinstall: node setup_bun.js
    • El archivo bun_environment.js, distribuido junto con ellos, contenía código malicioso ofuscado que descargaba y ejecutaba TruffleHog
  • TruffleHog escaneaba y robaba del entorno local tokens de NPM, credenciales de AWS/GCP/Azure y variables de entorno
  • La información robada se exfiltraba creando un runner de GitHub Actions llamado SHA1HULUD y usando un repositorio de GitHub con la descripción Sha1-Hulud: The Second Coming.
  • HelixGuard sugiere que este ataque podría provenir del mismo actor detrás del incidente “Shai-Hulud” ocurrido en septiembre de 2025

Análisis del funcionamiento del código malicioso

  • Como ejemplo, el análisis del paquete @asyncapi/specs mostró que la versión publicada en NPM estaba infectada, mientras que el repositorio fuente en GitHub seguía seguro
  • El atacante modificó package.json para añadir setup_bun.js y hacer que ese script llamara a bun_environment.js
  • bun_environment.js era un archivo JavaScript altamente ofuscado de más de 10 MB, cuyas funciones principales eran las siguientes
    • Recopilar credenciales y tokens de nube desde variables de entorno
    • Escanear secretos con TruffleHog
    • Exfiltrar datos mediante GitHub Actions
  • Además, modificaba package.json para insertar el código infectado y ejecutaba automáticamente npm publish, propagándose como un gusano

Infección en GitHub y exfiltración de datos

  • El script malicioso creaba el archivo .github/workflows/formatter_123456789.yml y registraba el runner SHA1HULUD
  • Ese workflow empaquetaba los secretos del repositorio en un archivo actionsSecrets.json con codificación Base64 doble
  • Después creaba un repositorio de GitHub con nombre aleatorio y la descripción Sha1-Hulud: The Second Coming., y subía allí los datos
  • HelixGuard confirmó que más de 27,000 repositorios de GitHub resultaron infectados
  • Entre los secretos robados había credenciales de múltiples servicios, incluidos AWS_ACCESS_KEY_ID, SLACK_WEBHOOK_URL, CODECOV_TOKEN y WEBFLOW_TOKEN

Lista de paquetes infectados

  • HelixGuard reportó que cientos de paquetes de NPM fueron infectados
    • Entre ellos había paquetes de organizaciones importantes como @asyncapi, @ensdomains, @posthog, @zapier, @postman y @voiceflow
    • Cada paquete tenía múltiples versiones infectadas, por ejemplo @asyncapi/specs@6.8.2 y @postman/csv-parse@4.0.5
  • La mayoría de los paquetes infectados suplantaban proyectos open source legítimos, con código malicioso insertado durante el proceso de despliegue automático

Implicaciones de seguridad

  • Este ataque muestra un caso de infección a gran escala del ecosistema open source mediante la explotación de debilidades en la seguridad de la cadena de suministro
  • También evidencia la necesidad de reforzar la seguridad en toda la infraestructura de desarrollo, incluidas credenciales de NPM, GitHub y servicios en la nube
  • HelixGuard recomienda detener de inmediato la instalación de los paquetes infectados y revocar inmediatamente los tokens y credenciales relacionados

5 comentarios

 
ahwjdekf 2025-11-27

El ecosistema de js realmente es el desastre de un basurero.

 
zihado 2025-11-25

Reaparición de Sha1-Hulud: más de 300 paquetes de NPM infectados

https://github.com/search/…

 
developerjhp 2025-11-25

Hice un script de escaneo en tiempo real.

En la ruta del repositorio sospechoso,
npx sha1-hulud-scanner
solo tienes que ingresarlo.

Código fuente: https://github.com/developerjhp/sha1-hulud-scanner

 
GN⁺ 2025-11-25
Opinión en Hacker News
  • Comparto un consejo: es mejor usar PNPM en lugar de NPM
    PNPM 10.x bloquea varios vectores de ataque
    1️⃣ Por defecto no ejecuta scripts de post-install y requiere aprobación manual
    2️⃣ Se puede configurar para que solo instale después de que pase cierto tiempo desde que se publica un nuevo release (por ejemplo, 4 días)
    NPM es demasiado inestable en entornos CLI de producción
    Conviene limitar las claves del publicador con el mínimo privilegio, vincularlas solo a paquetes específicos y atar la IP al runner de CI/CD
    No guardes claves de publicación en local; si hace falta, considera OIDC Trusted Publisher o acceso basado en tokens

    • NPM parece el resultado de demasiada deuda técnica acumulada
      Solo con el lockfile ya lo intentaron unas cinco veces y todavía no está del todo bien
      Viendo la estructura y el historial de commits, el equipo claramente está trabajando duro para mejorarlo, pero da la impresión de que empezaron desde un hoyo demasiado profundo
      Todavía no detecta EOF prematuro durante la transferencia de archivos y deja archivos incompletos en caché, así que en conexiones lentas se pierde muchísimo tiempo por actualizaciones fallidas
    • Yo prefiero el enfoque de secretos dinámicos de HashiCorp Vault / OpenBao
      Al principio es complejo, pero permite manejar secretos con el concepto de lease
      Se crea un lease para cada build de CI y se revoca automáticamente al terminar, además de soportar TTL y rotación automática
      Gracias a eso puedes ocultar credenciales de largo plazo y emitir tokens de vida corta solo en el momento del build
      Que ataques como este impulsen una verdadera discusión de seguridad dentro de la empresa es algo positivo
    • Basta con usar npm ci
      Como solo instala las versiones especificadas en package-lock.json, reduce el riesgo de ataques causados por actualizaciones automáticas
      Lo importante es tener el hábito de hacer solo actualizaciones intencionales
    • En el ecosistema de Python puedes conseguir una protección similar con la opción pip install --only-binary=:all:
      Bloquea por completo las distribuciones fuente e instala solo wheel
      Eso sí, puede introducir restricciones de versión
      En uv, la opción --exclude-newer puede imitar la función de “período mínimo desde el release” de PNPM
    • Hace poco vi un artículo sobre “dependency cooldown” y me identifiqué mucho
      Yo fijo todas las dependencias y reviso manualmente las alertas de dependabot
      Todavía me pregunto si eso es exagerado o simplemente una buena práctica
  • Hoy hay un artículo especialmente relevante: “We should all be using dependency cooldowns”
    Las actualizaciones automáticas de dependencias pueden ser más peligrosas que una vulnerabilidad de un solo día
    Es mucho más difícil revertir un paquete infectado que ya se propagó a miles de lockfiles

    • Creo que lo mejor es actualizar solo cuando realmente se necesita
      Si algo funciona bien, no hay razón para tocarlo
    • Pero incluso así, alguien más tiene que corregir los bugs, y si todos usan cooldowns, al final podríamos quedarnos estancados
    • En uv de Python puedes lograr algo parecido con el comando uv lock --exclude-newer $(date --iso -d "24 hours ago")
      La discusión relacionada está en issue #14992
    • También se puede hacer fácilmente con npm-check-updates
      Con el comando npx npm-check-updates -c 7 puedes configurar un cooldown de 7 días
      Consulta la documentación de npm-check-updates
    • No estoy de acuerdo con esa lógica
      Los cooldowns pueden alargar el tiempo de propagación de vulnerabilidades 0-day
      Si todos usan el mismo cooldown, lo único que se genera es retraso en la detección
  • Soy cofundador de PostHog
    Fuimos una de las víctimas de este ataque
    Las versiones infectadas son posthog-node 4.18.1, 5.13.3, 5.11.3 / posthog-js 1.297.3 / posthog-react-native 4.11.1 / posthog-docusaurus 2.0.6
    Ya rotamos todas las claves y contraseñas, y publicamos nuevas versiones
    Estamos analizando la causa y vamos a actualizar status.posthog.com

    • Recomiendo configurar una alerta para que se dispare si un nuevo release de paquete no está asociado a una ejecución de CI/CD
    • Me pregunto si el JS infectado llegó a afectar a usuarios reales
      Si un sitio web desplegó la versión infectada, quisiera saber si hubo impacto para los visitantes
    • Si todavía no se conoce la causa, existe la posibilidad de que el ataque siga propagándose
    • La versión más reciente también podría estar infectada, así que no está claro por qué la gente debería confiar esta vez
    • Menos mal que esta actualización se ve más aquí que en el aviso de Twitter. Ojalá se recuperen pronto
  • Pregunta seria: ¿realmente tiene sentido empezar un proyecto nuevo con Node?
    Estoy construyendo un frontend SaaS con Astro y cada vez que actualizo dependencias me siento intranquilo
    La falta de seguridad en el ecosistema npm se siente demasiado grave

    • El problema no es Node ni JS, sino el modelo de empaquetado
      Ecosistemas como Rust, que también dependen de muchísimos subpaquetes, tarde o temprano van a pasar por lo mismo
      Quizá no tener package manager, como en C, C++ u Odin, sea incluso una decisión más sensata desde la seguridad
    • Yo creo que el problema es npm en sí, más que Node
      Últimamente confío más en JSR de Deno
      Los paquetes basados en JSR también se publican de forma cruzada en npm, y además hay paquetes exclusivos para Deno
      Por ejemplo, Lume me impresionó como SSG lento pero estable
    • No es un problema exclusivo de Node
      npm simplemente es el repositorio más grande, así que para los atacantes tiene más valor
      Esto perfectamente podría pasar también en RubyGems o Cargo
    • La idea de evitar Node es exagerada
      Solo recibe más ataques porque es el ecosistema más usado
      Basta con gestionar las dependencias con cuidado y no actualizar todos los días
    • Nosotros desarrollamos una plataforma de análisis de seguridad de productos en PHP
      Una ventaja es que no necesitas más de 100 dependencias para renderizar una página
      Consulta el enlace del proyecto
  • Últimamente hago todo mi desarrollo solo dentro de contenedores de Podman
    Todo código que no he leído lo ejecuto obligatoriamente en un entorno aislado
    No es perfecto, pero me parece un hábito mínimo de seguridad

    • La mayoría de la gente no percibe el riesgo porque en el 99.99% de los casos no pasa nada
      La seguridad suele ser un área que se delegada a especialistas, así que en la práctica es difícil cambiar eso
    • Los paquetes de npm tienen árboles de dependencias demasiado profundos; me pregunto cómo funciona el aislamiento con contenedores en esos casos
    • Quisiera entender de forma más concreta cómo manejar dentro de un contenedor paquetes npm como el SDK de PostHog
    • Podman es más seguro que Docker, y si hace falta también valdría la pena considerar aislamiento adicional como QEMU
    • Yo directamente me conecto por SSH con otro usuario local y desarrollo en tmux
  • Hace 12 años NPM llegó a quedar completamente caído una vez
    En ese momento era solo un proyecto open source, pero ahora pertenece a Microsoft
    Si lo posee una de las empresas más grandes del mundo, ¿no debería poder resolver este tipo de problemas?
    Pero la verdad es que no parece haber cambiado mucho

    • MS ni siquiera puede gestionar bien Windows
      Todo lo que no da dinero con licencias empresariales lo dejan abandonado
      Por eso Windows 11 parece más un bloque de marketing que otra cosa
  • Actualmente estamos monitoreando la actividad del ataque y actualizando la lista de paquetes infectados en el blog de Wiz
    Estamos haciendo ingeniería inversa del payload malicioso y esperamos compartir resultados en unas horas

  • Me molestó que el chat de “Talk to a human” de PostHog en realidad diera respuestas de robot
    Además, el enlace de soporte urgente no orienta bien
    Así que quiero preguntar: ¿qué versiones hay que evitar?

    • Soy cofundador. Ya lo anunciamos en el hilo principal y en status.posthog.com
      Las versiones infectadas son posthog-node 4.18.1, 5.13.3, 5.11.3 / posthog-js 1.297.3 / posthog-react-native 4.11.1 / posthog-docusaurus 2.0.6
      Si actualizas a la versión más reciente, estás a salvo
    • También compartieron la misma lista de versiones en el canal de Slack
  • Me pregunto por qué este tipo de caos con paquetes siempre pasa en el ecosistema Node
    No entiendo por qué esta comunidad cree que hooks de instalación complejos y actualizaciones automáticas son buena ingeniería
    Ahora entiendo por qué el creador de Node ya se fue

    • Node es el nuevo PHP
      Un ecosistema enorme, centrado en desarrolladores principiantes, con poca conciencia de seguridad, y donde incluso funciones pequeñas dependen de librerías
    • Un ecosistema serio debería tener maintainers de paquetes
      Como en Debian, debería haber administradores de confianza que validen las cosas, pero la comunidad de JS lo rechaza por considerarlo gatekeeping
      Por eso esta clase de incidentes se repite
    • Rebajar a otros para sentirse superior solo sirve por un momento
      Con esa actitud no va a cambiar nada
  • Un poco fuera de tema, pero me da curiosidad quién es HelixGuard
    Su sitio web está mal hecho y casi no hay información
    Dicen que sus clientes son exchanges de criptomonedas, pero todo se ve medio sospechoso

 
laeyoung 2025-11-25

2️⃣ Se puede configurar para que solo se instale después de que pase cierto tiempo (por ejemplo, 4 días) tras la distribución de una nueva versión.

Es una función buenísima. A veces Google también sube a NPM versiones con bugs o que no funcionan, así que hay momentos en que me saco de onda pensando si el bug es mío.