El ataque a la cadena de suministro de Tensorlake en npm y la trampa del borrado de tokens

Ya están disponibles los parches de php2shell (CVE-2026-109618 y CVE-2026-109619) para PHP en fin de vida útil. Dado que las respuestas del departamento de ventas están tardando más de lo habitual debido a la elevada demanda, la forma más rápida de obtener los paquetes parcheados es comprar ELS para Runtimes en línea (se abre en una pestaña nueva). Lee las preguntas frecuentes sobre los parches

Ir directamente al resumen generado por IA de esta entrada del blog

  • Resume esta entrada con Perplexity
  • Resume esta publicación con Gemini

La versión resumida

¿Qué: Un malicioso [email protected] Se publicó en npm a las 01:12 UTC del 8 de octubre de 2026. Esta vez no se trata de un «typosquat». Es el auténtico SDK de Tensorlake para TypeScript, creado mediante el flujo de trabajo propio del proyecto y con procedencia válida de Sigstore. A preinstall Hook utiliza Bun para ejecutar una carga útil ofuscada de ChainDrop / Shai-Hulud de 856 KB.

Repercusión: Socket registra unas 12 000 descargas semanales, mientras que Aikido supera las 100 000 instalaciones totales. Allí donde se ejecuta el «hook», roba credenciales, contraseñas del navegador y configuraciones de herramientas de IA. Si el token de GitHub robado pertenece a una cuenta que no forma parte de ninguna organización, también instala un monitor que intenta borrar el directorio de inicio cuando se revoca dicho token.

Estado: Socket lo señaló en 11 minutos, y Noticias Hacker Según se informa, npm lo ha retirado. Tensorlake ha revertido las modificaciones en solicitud de incorporación de cambios n.º 1016. En el momento de escribir este artículo, la versión 0.5.145 aún no se había lanzado y seis tensorlake-native-* Los paquetes seguían estando disponibles en la versión 0.5.144. ¿Lo has instalado? Haz una copia de seguridad, retira el monitor y, a continuación, gíralo.

La versión larga

¿Te afecta esto?

Hay dos cuestiones importantes. ¿Se ha resuelto la versión 0.5.144 en algún lugar que te interese? ¿Y se ha ejecutado allí su script de instalación?

Lo primero depende de cómo lo instales. tensorlake todavía pertenece a la línea 0.x, por lo que un rango como ^0.5.140 acepta sin problemas cualquier parche 0.5 posterior. Los proyectos que se instalan a partir de un archivo de bloqueo existente con npm ci se mantuvo sin cambios. El riesgo provenía de resolver la nueva versión mientras la versión defectuosa seguía activa, a través de npm update, una solicitud de incorporación de cambios de Dependabot o Renovate fusionada esa misma mañana, una primera instalación o un Dockerfile que copia package.json sin el archivo de bloqueo. Cualquiera que haya descargado la rama principal del repositorio entre el 7 de octubre y la reversión de Tensorlake y haya ejecutado npm install en typescript/ También ejecuté el script, sin necesidad de registrarlo.

En cuanto a la segunda pregunta, no fue necesario importar el SDK. Bastó con instalarlo con los scripts de ciclo de vida activados, incluso en una compilación que falló un minuto después. Con ignore-scripts=true en .npmrc, el hook nunca se ejecutó. npm 12 y pnpm 10 y versiones posteriores retienen los scripts de dependencias hasta que los apruebes (npm 11 solo muestra un aviso), y Bun solo los ejecuta para los paquetes que figuran en su lista de confianza, pero comprueba tu configuración antes de darlo por hecho. StepSecurity Se ha descubierto que el cargador se cierra cuando detecta CI, lo que da prioridad a los portátiles de los desarrolladores. Esto reduce el riesgo de CI sin descartarlo por completo, ya que Socket siguió encontrando la recopilación de credenciales de CI en la carga útil.

En rg Esta línea sirve para una clasificación inicial, así que trata cualquier 0.5.144 en un tensorlake línea como pista. Omite los archivos «.gitignored» y los binarios, lo que significa que un binario más antiguo bun.lockb no aparecerá:

npm ls tensorlake --all
npm ls --all | grep tensorlake-native
pnpm why tensorlake
yarn why tensorlake
rg -n 'tensorlake' -g '*lock*' -g 'npm-shrinkwrap.json' .

A continuación, comprueba el disco y el perfil de usuario:

find "$HOME" -path '*/node_modules/tensorlake/lib/Math_Symbol.js' 2>/dev/null
ls -la ~/.config/gh-token-monitor ~/.local/bin/gh-token-monitor.sh 2>/dev/null

Amplía el find para crear cachés y procesos de ejecución, o utilizar EDR en flotas gestionadas. Confirma cualquier Math_Symbol.js Aplicar los hash en «Mitigación». A gh-token-monitor Si aparece en el directorio, significa que la trampa está activada, así que pasa directamente a la sección de «Mitigación». Si no aparece, no se considera que el host está limpio, ya que el monitor solo se activa para algunas cuentas.

En qué consiste el ataque Tensorlake

Tensorlake ejecuta código no fiable generado por modelos en entornos aislados (sandboxes), y el SDK de npm es la forma en que las aplicaciones de TypeScript los controlan. Los equipos aíslan todo lo que escriben sus agentes y, a continuación, instalan el SDK en un portátil que tiene acceso a todo. El entorno aislado nunca falló. El malware se ejecutó en el equipo de instalación antes de que se activara ningún entorno aislado.

El atacante accedió a través del repositorio de código fuente. Según StepSecurity, la primera confirmación maliciosa, e90c47b, aterrizó en la pista principal a las 01:20 UTC del 7 de octubre, seguido de otros siete que ajustaron la carga útil y añadieron el preinstall línea. Ninguna de ellas pasó por una solicitud de incorporación de cambios. Según el propio informe de Tensorlake, procedían de una cuenta de administrador del repositorio a través de la interfaz web de GitHub, razón por la cual Aikido las vio marcadas como «verificadas». GitHub firma automáticamente las confirmaciones realizadas a través de la interfaz web, por lo que la insignia indicaba que se trataba de una cuenta que había iniciado sesión y nada más. No se ha hecho público cómo se vio comprometida dicha cuenta.

Aproximadamente un día después, la misma cuenta publicó manualmente el vídeo del repositorio publish_npm.yaml flujo de trabajo. Se compiló, firmó y publicó la versión 0.5.144. El escáner de Socket lo detectó a las 01:23:10 UTC, y StepSecurity lo notificó a los responsables del mantenimiento en Incidencia de GitHub n.º 1014. Los nombres de los archivos coinciden con la tanda de ChainDrop de agosto a través de keyv, y el aikido encontró un WORMTAG un indicador que apunta a una nueva infección, en lugar de a una reinfección residual.

Cómo funciona el «Hostage Token»

Cuando la carga útil obtiene un token de GitHub de una cuenta que no pertenece a ninguna organización, instala un servicio llamado gh-token-monitor, según Descodificación de SafeDep. Los tokens de las cuentas que pertenecen a una organización se roban de la misma manera, sin necesidad de ningún truco. Se trata de una unidad de usuario de systemd en Linux, un LaunchAgent en macOS y una tarea programada al iniciar sesión en Windows. Cada 60 segundos, durante un máximo de 24 horas, llama a api.github.com/user con el token robado. Según StepSecurity, una vez que GitHub rechaza el token, se ejecuta rm -rf ~/ en Linux y macOS, o mediante un comando de PowerShell para eliminar el perfil de usuario en Windows. El código incluso contiene la cadena IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner, y GMO Flatt Security se ha informado de que se han eliminado archivos en los equipos infectados.

Si consultas prácticamente cualquier guía de actuación ante el robo de credenciales, verás que el primer paso es revocar el token. En un host en el que este monitor siga en funcionamiento, ese paso puede provocar la eliminación del directorio de inicio del desarrollador, independientemente de si la revocación la lleva a cabo el propio desarrollador, un administrador o un guion automatizado. Si la automatización revoca los tokens vinculados a hosts marcados, manténlos activos para los hosts afectados hasta que los monitores hayan desaparecido.

Desconectar el cable de red tampoco es una solución garantizada, ya que nadie ha publicado cómo gestiona el monitor una conexión fallida. Guarda los datos críticos, avisa a tu equipo de respuesta ante incidentes para que adopte medidas de contención y actúa con rapidez, porque el atacante puede seguir utilizando ese token durante todo ese tiempo.

En el interior de la carga útil

El cargador comprueba si hay CI; si lo encuentra, se cierra; descarga Bun y pasa el control a Math_Symbol.js, por lo que el trabajo real se lleva a cabo en un proceso que no es node.

Busca tokens de npm, incluido el intercambio OIDC utilizado por la publicación de confianza, y extrae datos de los metadatos de las instancias de AWS, de Secrets Manager y de SSM Parameter Store, que, según observó GMO Flatt Security, leía en todas las regiones. Sondea un Vault local en 127.0.0.1:8200 y analiza los tokens de Kubernetes, las claves SSH, .env archivos, configuraciones de Docker y carteras de criptomonedas. Aikido ha detectado que deja un archivo llamado «HackBrowserData» con las contraseñas y las cookies guardadas. También se centra en los archivos de configuración y MCP de Claude, Cursor, Kiro, Windsurf y Zed, que suelen contener claves API en texto sin cifrar.

Los datos robados se envían, cifrados, a iseekaigogo.com, el dominio C2 codificado de forma fija en la carga útil, o a un nuevo repositorio público en la propia cuenta de GitHub de la víctima, denominado «Shai-Hulud: Here We Go Again». Como alternativa, Aikido detectó que el malware leía un contrato de Ethereum controlado por el atacante en 0xb614155Fd88114d40549b259457Bcf921Df091B9 para un dominio alternativo. Su última actualización, el 21 de septiembre desde el monedero 0x779f83aE56309682beDb04816c19d358c4B21040, apunta al mismo dominio. Eliminarlo ayuda, pero basta una sola transacción para redirigirlo.

A continuación, se propaga. Con un token de npm, se introduce en los paquetes de la víctima, aumenta el número de versión, genera la procedencia de Sigstore y vuelve a publicarlos. Con un token de GitHub, realiza un commit .claude/settings.json y .vscode/tasks.json a los repositorios a los que pueda acceder, utilizando el autor [email protected] y el mensaje «tarea: actualizar dependencias». Los hooks de Claude Code pueden ejecutar comandos de shell y las tareas de VS Code pueden ejecutarse al abrir una carpeta, por lo que esos archivos pueden suponer una vía de acceso, dependiendo de cómo estén configurados y de los ajustes de confianza del siguiente desarrollador.

Qué debería cambiar en la fase de admisión

La información sobre la procedencia de la versión 0.5.144 es correcta. Indica correctamente que el paquete procede de tensorlakeai/tensorlake a través del propio flujo de trabajo del proyecto, que es precisamente lo que la procedencia siempre afirma. Cuando una cuenta de administrador realiza un commit directamente en la rama «main», el proceso de compilación real genera el malware y lo firma. Una política que compruebe la procedencia, pero que nunca examine el código certificado, habría aceptado esta versión.

Los archivos de bloqueo solo servían por inercia, y el escáner de CVE no encontró ninguna coincidencia. Por otra parte, la diferencia entre las versiones 0.5.143 y 0.5.144 era difícil de pasar por alto, con una nueva preinstall un script, un nuevo cargador y un archivo ofuscado de 856 KB en una versión de parche. Pocos equipos leen las diferencias de los archivos tarball para detectar cambios en los parches, pero en los archivos de bloqueo de npm más recientes, un cambio en el hasInstallScript La entrada es una apuesta fácil de seguir.

El tiempo también ayuda. Socket lo detectó en 11 minutos, por lo que un filtro de antigüedad de 24 horas (el de npm) min-release-age, o los de pnpm minimumReleaseAge, cuyo valor por defecto es de 24 horas a partir de pnpm 11) lo habría excluido de la mayoría de las compilaciones. La respuesta de Tensorlake, expuesta en la solicitud de incorporación de cambios n.º 1016, también constituye una plantilla adecuada, en la que se ha eliminado la opción de omisión de administración de la rama principal, se exigen confirmaciones firmadas, se requiere un segundo revisor para las publicaciones en npm y se ha establecido un mecanismo de alerta de CI que falla si un manifiesto publicado declara un script de instalación. En cuanto a los usuarios, detén cualquier actualización de dependencia que añada o modifique un script de instalación. Un paquete que no lo tenga puede seguir ejecutando código al importarse, pero merece la pena detener el proceso si se trata de un script nuevo.

Mitigación

El orden es más importante de lo habitual. Considera que cualquier servidor en el que se haya ejecutado el «hook» está comprometido y sigue tu procedimiento de gestión de incidentes.

Guarda primero los datos críticos. Copia en un dispositivo de almacenamiento externo el trabajo no guardado y otros datos irremplazables —no las herramientas— antes de tocar los tokens, los servicios o la red. Conserva los archivos de bloqueo y los registros de instalación como prueba.

Confirma los artefactos. Comprueba las estaciones de trabajo, los hosts de compilación y las imágenes creadas el 7 u 8 de octubre comparándolas con los valores SHA-256 publicados. lib/setup.mjs es 25a0735d0db7dc40e5d45ce42d9c106067e6a66e184d967cfecfab17c3bcb5ef y lib/Math_Symbol.js es b50a00900399ba99fb6ce1fc151519cb99d44320ef2a631f2237e1aea0ad6fec. GMO Flatt Security incluye en su lista un archivo al que denomina artifact.tar.gz como 33108f494dad71369a9aa7cd6daa5402335d1a718b78320b9b687c0b2174fa67, y la copia del registro de publicación de SafeDep indica que el SHA-1 del archivo tar de npm es 843a898ab72793568d77c53ff9282e6ce7c66aea. Los hash confirman una coincidencia, pero no detectan una copia modificada.

Desactiva el monitor antes de revocar cualquier cosa. El archivo en ~/.config/gh-token-monitor/ contiene el token de vigilancia. Trátalo como información confidencial y no lo incluyas en los tickets ni en el chat. StepSecurity ha publicado los siguientes comandos para Linux y macOS, con un daemon-reload Se han añadido aquí. Comprueba los nombres y las rutas en el propio equipo antes de ejecutarlos:

# Linux
systemctl --user disable --now gh-token-monitor.service
rm -rf ~/.config/gh-token-monitor
rm -f ~/.local/bin/gh-token-monitor.sh
rm -f ~/.config/systemd/user/gh-token-monitor.service
systemctl --user daemon-reload

# macOS
plist=~/Library/LaunchAgents/com.user.gh-token-monitor.plist
launchctl bootout gui/(id-u)"plist"
rm -rf ~/.config/gh-token-monitor
rm -f ~/.local/bin/gh-token-monitor.sh
rm -f "$plist"

En Windows, este PowerShell de solo lectura muestra las tareas programadas que se ejecutan monitor.ps1, por lo que puedes eliminarlos mediante tus herramientas de gestión de terminales:

Get-ScheduledTask | Where-Object {
  "(_.Actions.Execute) (_.Actions.Arguments)" -match 'monitor\.ps1'
}

Asegúrate de que ya no está antes de seguir adelante. Eliminar node_modules No lo voy a tocar, y quitar este monitor no demuestra que no haya otros datos persistentes.

Realiza la rotación desde una máquina limpia. Revoca el token de GitHub supervisado; así, se bloqueará el acceso a todo aquello a lo que pudiera acceder esa cuenta, incluidas las credenciales de npm, la nube, SSH, Kubernetes, Vault y el registro, .env secretos, así como las claves de herramientas de IA y de la API de MCP. Considera que las contraseñas y las sesiones del navegador están expuestas y, ya que estás, cierra las sesiones activas.

Limpia los repositorios y comprueba lo que publicas. Busca las modificaciones de [email protected] con «tarea: actualizar dependencias», stray .claude/settings.json o .vscode/tasks.json archivos, flujos de trabajo desconocidos y nuevos repositorios públicos con la descripción «Shai-Hulud: Here We Go Again». Si se ha filtrado el token de npm de un responsable de mantenimiento, busca versiones que nadie de tu equipo haya publicado.

Bloquear y revisar la salida. Bloque iseekaigogo.com por dominio. Listas de Flatt 172.67.207.33 y 104.21.22.217 como direcciones, pero se trata de direcciones IP compartidas de Cloudflare, así que utilízalas en búsquedas en los registros, no en las reglas del cortafuegos.

Si tienes dudas, bloquea, aplica las medidas de seguridad y vuelve a instalar la imagen. Esperar tensorlake en la versión 0.5.143, lo que también fija sus paquetes nativos en la versión 0.5.143, hasta que Tensorlake publique y confirme la versión 0.5.145. Mantener tensorlake-native-* desinstalar la versión 0.5.144. Reinstalar en un servidor sin datos, guardar el archivo de bloqueo y utilizar npm ci en CI. Si no puedes dar cuenta de todos los puntos de persistencia, vuelve a crear la máquina a partir de una imagen que sepas que funciona correctamente.

Detección

La cadena de procesos es la mejor indicación. Busca npm o node desove node lib/setup.mjs, que a continuación se descarga y se ejecuta bun. La aparición de «bun» en la instalación de un paquete en un equipo que nunca lo ha tenido ya es sospechosa de por sí, al igual que los elementos de instalación que indican .npmrc, .aws, .kube, claves SSH o perfiles de navegador.

Para garantizar la persistencia, configura alertas sobre las unidades de usuario de systemd, los LaunchAgents o las tareas ONLOGON creadas bajo un proceso Node o Bun. Un proceso que no sea de navegador y que realice sondeos api.github.com/user «Una vez por minuto» es más o menos la descripción más concreta que podrás obtener.

Cómo SecureChain para JavaScript cambia el resultado

SecureChain para JavaScript adelanta la decisión de confianza a una fase anterior, antes de que un paquete llegue a un ordenador portátil. Recompila los paquetes a partir del código fuente en entornos reforzados y aislados, y los analiza en busca de malware conocido, patrones de código sospechosos y riesgos en la cadena de suministro, bloqueando todo aquello que no supere la inspección. Una simple recompilación por sí sola no habría salvado a nadie en este caso, ya que el código malicioso se encontraba en el código fuente original. Es el análisis lo que detecta esto, y el lanzamiento de un parche que de repente añade un preinstall El hecho de que el hook descargue un segundo entorno de ejecución y ejecute 856 KB de código JavaScript ofuscado es precisamente el tipo de cambio que está diseñado para impedir.

Descubre SecureChain para JavaScript →

Se trata de un sustituto de repositorio listo para usar, compatible con JFrog Artifactory, Sonatype Nexus y GitHub Packages, por lo que el npm Los comandos siguen siendo los mismos, y ofrece información de procedencia según el nivel 3 de SLSA, SBOM y salida VEX. Es compatible con JavaScript, Python, Java, Go, Rust y PHP. Y cuando incidentes como este obligan a los equipos a dejar de utilizar una dependencia hasta que supere su fin de vida útil, el servicio «Endless Lifecycle Support» de TuxCare puede seguir proporcionando correcciones de seguridad para esa versión mientras sigas dependiendo de ella. Sin actualizaciones obligatorias ni reescrituras.

Por qué esto va más allá de un simple paquete

En mayo se produjo una oleada de Mini Shai-Hulud a través de TanStack que llevaba una procedencia SLSA válida, y en junio se produjo el «typosquat» de Mastra. En agosto se produjo ChainDrop a través de keyv y el compromiso de la referencia de matriz en crates.io. Ahora, la misma familia de gusanos ha llegado a la infraestructura de los agentes de IA. Lo que se repite una y otra vez es que los defensores consideran que un editor autenticado o una certificación válida son prueba de que el código es correcto. En este caso, tanto el nombre del paquete como su procedencia eran reales. Simplemente respondieron a una pregunta diferente a la que realmente importaba.

Descubre SecureChain para JavaScript →

PREGUNTAS FRECUENTES

¿Qué versiones de Tensorlake son seguras?

La versión 0.5.143 es la última versión «limpia» y seguía siendo la de npm latest en el momento de redactar este artículo. Actualiza a la versión 0.5.145 en cuanto Tensorlake la publique, y mantén tensorlake-native-* excepto 0,5,144.

¿Es seguro revocar inmediatamente el token de GitHub que me han robado?

No, si el monitor aún pudiera estar en funcionamiento. En un servidor donde gh-token-monitor Si está activo, revocar su token puede provocar la eliminación del directorio de inicio o del perfil de usuario. Conserva los datos, retira el monitor, luego revoca y renueva el token, y hazlo rápidamente.

Únase a más de 4.500 profesionales de Linux y el código abierto.

2 veces al mes. Sin spam.

Índice
Obtenga las respuestas de seguridad de código abierto que necesita

Únase a más de 4.500 profesionales de Linux y el código abierto.

2 veces al mes. Sin spam.