Todos los artículos

La provenance de npm no es un control de seguridad: el gusano tensorlake

Node.js · 4 min de lectura ·

La insignia verde de provenance en un paquete npm te dice dónde se construyó el paquete. No te dice que el código sea seguro. Según el rastreador de incidentes pwn.watch, tensorlake@0.5.144 se publicó el 8 de octubre de 2026 desde el repositorio real del proyecto en GitHub, con provenance de npm, y traía un hook preinstall que instala un gusano ladrón de credenciales del tipo Shai-Hulud. Si tu equipo trata la provenance como una señal de confianza, este es el caso que conviene leer, porque la insignia era auténtica.

Qué informa el rastreador

Lo que sigue en esta sección es el resumen del rastreador, la versión de un solo agregador; lo que hay que comprobar antes de actuar es el aviso del propio paquete. El rastreador marca la entrada como parcialmente corregida. Dice que el hook recoge secretos de npm, GitHub, la nube, SSH y herramientas de IA, se propaga a otros paquetes e instala un vigilante llamado "gh-token-monitor" que borra el directorio personal si se revoca el token de GitHub robado. Su consejo: fijar 0.5.143 y eliminar ese vigilante antes de rotar tokens. Ese último punto invierte el instinto habitual de revocar primero, y por eso importa.

Qué prueba la provenance y qué no

Esto es conocimiento general sobre cómo funciona la provenance. La provenance es una declaración firmada de que un repositorio y un workflow concretos produjeron el paquete. Cierra bien un hueco: quien publique una imitación desde un portátil con un token robado no puede falsificarla. No dice nada sobre si el código de ese repositorio, en ese momento, es benigno. Si un atacante entra en el pipeline de build o en la cuenta de un mantenedor, la versión maliciosa se construye desde el repositorio real y lleva provenance real.

El código que se commiteó Qué repositorio Qué workflow Este archivo de paquete exacto la provenance cubre estos eslabones sin cubrir: ¿el código es benigno? tampoco cubre esto: un pipeline o un token de mantenedor secuestrado sigue generando una versión con provenance válida
La provenance responde a "dónde se construyó esto", nunca a "este código es seguro".

GitHub ha ido endureciendo el lado de la publicación. Su changelog dice que las configuraciones de trusted publishing de npm que no se validan caducan ahora a las 48 horas, que se rechazan los tokens de trusted publishing procedentes de eventos issue_comment, y que npm stage publish exige que un mantenedor promueva la primera versión de un paquete nuevo. GitHub también dice que el malware actúa cada vez más en el momento de la instalación, recogiendo credenciales en hosts de CI y estaciones de trabajo sin que tu app llegue a ejecutar el código del paquete. Esa es la forma de este incidente, y por eso la defensa tiene que estar en la instalación.

El camino de npm install a tus secretos

Conocimiento general otra vez: los scripts preinstall e install se ejecutan durante npm install con los permisos de tu usuario, así que lo que pueda leer tu shell lo puede leer el script. En un portátil, eso son tus claves SSH y tu configuración de la nube. En un runner de CI, es cada secreto inyectado en el job.

npm install Recoge una versión nueva Ejecuta su script de install Lee tus secretos corte 1 lockfile, espera corte 2 --ignore-scripts corte 3 sin secretos donde instalas
Tres sitios donde romper la cadena, cada uno útil aunque fallen los otros.

Corte 1, elige qué se instala. Haz commit del lockfile e instala a partir de él, para que una versión nueva solo llegue cuando tú lo decidas. Un periodo de espera, es decir, no adoptar versiones con menos de unos días, te da tiempo, porque las versiones maliciosas suelen detectarse en pocos días. El firewall de paquetes de GitHub, en vista previa pública solo para Enterprise Cloud y npm, ofrece una espera configurable de este tipo. Corte 2, no ejecutes scripts de instalación por defecto. npm ci --ignore-scripts se los salta; algunos paquetes de verdad necesitan los suyos, así que permite esos a propósito. Corte 3, mantén los secretos lejos del paso de instalación. Un job de CI que instala dependencias no necesita tus claves de despliegue en su entorno.

npm ci --ignore-scripts
npm ls tensorlake
La provenance te dice quién construyó un paquete, no si debes ejecutarlo: fija versiones desde un lockfile y no dejes que los scripts de instalación vean tus secretos.

Si tensorlake 0.5.144 se ejecutó en una máquina

El orden general es: aislar la máquina o el runner, averiguar qué se ejecutó y después rotar cada secreto que pudo leer, desde una máquina limpia. En este caso, según el rastreador, busca y elimina el vigilante del token antes de revocar el token de GitHub. Contrasta cada paso con el aviso del propio paquete, no solo con este resumen.

Fuente: el rastreador de incidentes pwn.watch, entrada "tensorlake@0.5.144 npm Shai-Hulud worm with hostage GitHub token".

Notas de los lectores

  1. Todavía no hay notas. La primera siempre es la más valiente.
¿Estás construyendo algo parecido? Puedo ayudarte. Escríbeme por WhatsApp