
Comprobador de IOC para el ataque a la cadena de suministro de npm TanStack/Mini Shai-Hulud (CVE-2026-45321)
curl -fsSL https://raw.githubusercontent.com/nkopylov/tanscript-exploit-check/main/check-tanstack-exploit.sh | bash
O clonar y ejecutar localmente:
git clone https://github.com/nkopylov/tanscript-exploit-check.git
cd tanscript-exploit-check
./check-tanstack-exploit.sh [directorio_del_proyecto ...]
Este comprobador cubre dos oleadas de la campaña de ataque a la cadena de suministro Mini Shai-Hulud por parte de TeamPCP:
El 11 de mayo de 2026 (19:20-19:26 UTC), un atacante publicó 84 versiones maliciosas en 42 paquetes @tanstack/* de npm en una ventana de 6 minutos. El ataque también afectó a paquetes de Mistral AI, UiPath, OpenSearch y otros, con más de 170 paquetes en total en npm y PyPI.
No se robaron credenciales de mantenedores. El atacante explotó la propia cadena de confianza del CI/CD mediante un ataque de 3 etapas:
pull_request_target — Un fork de GitHub desechable abrió un PR que ejecutaba código del atacante en el contexto de seguridad del repositorio base.El 19 de mayo de 2026 (01:39-02:06 UTC), la cuenta comprometida de npm atool ([email protected]) publicó 637 versiones maliciosas en 314 paquetes en dos oleadas automatizadas. Los objetivos de alto impacto incluyen:
size-sensor (4.2M descargas/mes)echarts-for-react (3.8M descargas/mes)@antv/scale (2.2M descargas/mes)timeago.js (1.15M descargas/mes)@antv/* y otrosEsta oleada utilizó una carga útil basada en Bun (498KB index.js) activada mediante "preinstall": "bun run index.js", con una carga útil de segunda etapa oculta en commits impostores enviados al repositorio de GitHub antvis/G2 mediante la explotación del objeto compartido del fork.
Ambas oleadas utilizan la misma familia de herramientas "Mini Shai-Hulud":
gh-token-monitor (Oleada 1) y kitty-monitor (Oleada 2) mediante LaunchAgent/systemd; hooks en .claude/settings.json y .vscode/tasks.json.toJSON(secrets), intercambio de tokens OIDC de npm.rm -rf ~/ si el token de GitHub se revoca mientras el daemon está activo.firedalazer, comandos firmados con RSA-PSS.Solo se vieron afectados @tanstack/router* y @tanstack/start*. NO afectados: @tanstack/query*, @tanstack/table*, @tanstack/form*, @tanstack/virtual*, @tanstack/store.
Consulte el aviso completo para los 42 paquetes.
Todos los paquetes publicados por el usuario de npm atool ([email protected]) recibieron versiones maliciosas el 19 de mayo de 2026. Los paquetes de alto impacto incluyen:
| Paquete | Descargas mensuales |
|---|---|
size-sensor | 4.2M |
echarts-for-react | 3.8M |
@antv/scale | 2.2M |
Además de 310+ paquetes principalmente en el ámbito @antv/* (@antv/g2, @antv/g6, @antv/l7, @antv/s2, @antv/x6, @antv/f2, etc.), ai-figure, timeago-react, jest-canvas-mock, jest-date-mock y otros.
Consulte el informe de SafeDep para la lista completa.
CRÍTICO: Deshabilite el interruptor de hombre muerto ANTES de revocar cualquier token. El malware borra
$HOMEsi los tokens se revocan mientras el daemon está activo.
gh-token-monitor Y kitty-monitor) y elimine los servicios de LaunchAgent/systemd..claude/router_runtime.js, .vscode/setup.mjs, ~/.local/share/kitty/cat.py, /var/tmp/.gh_update_state, etc.)node_modules y los archivos lock, reinstale con --ignore-scriptsapi.masscan.cloud, filev2.getsession.org, git-tanstack.com, t.m-kosche.com)Copie y pegue estas indicaciones en su agente de codificación de IA (Claude Code, Cursor, Cline/OpenClaw, Windsurf, Hermes, etc.) para endurecer su proyecto contra ataques a la cadena de suministro como este.
Endurece la configuración npm de este proyecto contra ataques a la cadena de suministro. Haz lo siguiente:
Fija versiones exactas: Elimina todos los prefijos
^y~de cada dependencia enpackage.jsonpara quenpm installnunca obtenga silenciosamente una versión recién publicada.Deshabilita los scripts postinstall por defecto: Añade
ignore-scripts=truea.npmrc. Luego añade un script"preinstall"explícito enpackage.jsonque ejecute solo los scripts de ciclo de vida conocidos y seguros que este proyecto realmente necesite (si los hay).Exige instalaciones solo desde lockfile en CI: Asegúrate de que CI use
npm ci(nonpm install). Si hay un archivo de configuración de CI, verifícalo. Si no, indícalo como paso manual.Añade verificación de procedencia: Añade
npm audit signaturescomo paso en el pipeline de CI y como hook pre-push de git.
Audita y endurece la configuración del agente de codificación de IA de este proyecto contra ataques de inyección en la cadena de suministro (como la campaña TanStack/Mini Shai-Hulud que inyectó hooks maliciosos en
.claude/settings.jsony.vscode/tasks.json). Haz lo siguiente:Claude Code (
.claude/):
- Revisa
.claude/settings.jsony.claude/settings.local.jsonen busca de entradashooksque ejecuten comandos de shell. Señala cualquier cosa que ejecute archivos.js,.mjso.sh, especialmente desde dentro de.claude/,.vscode/onode_modules/.- Elimina cualquier hook que no puedas rastrear hasta un propósito legítimo y creado por el usuario.
Audita y endurece la configuración de GitHub Actions en este repositorio contra ataques a la cadena de suministro de CI/CD. Haz lo siguiente:
Elimina o refactoriza cualquier disparador
pull_request_target— estos ejecutan código del flujo de trabajo en el contexto del repositorio base con acceso a secretos, incluso cuando se activan mediante un fork. Reemplázalos conpull_request+ un flujo de trabajo separado con aprobación si es necesario.Fija todas las acciones de terceros a commits SHA completos (no etiquetas o ramas). Por ejemplo, reemplaza
actions/checkout@v4conactions/checkout@<sha-completo>. Añade un comentario con la etiqueta para legibilidad.Aplica permisos de mínimo privilegio a cada flujo de trabajo. Añade bloques
permissions:explícitos. La mayoría de los flujos de trabajo solo necesitancontents: read. Los flujos de trabajo de publicación necesitanid-token: write— y nada más.Restringe el ámbito de la caché: Si usas
actions/cache, asegúrate de que las claves de caché tengan ámbito por rama para evitar el envenenamiento entre ramas. Añaderestore-keyscon cuidado — no restaures cachés de ramas no confiables.
MIT
| # | Comprobación | Descripción |
|---|
| 1 | Interruptor de hombre muerto | Demonios de persistencia: gh-token-monitor (Oleada 1), kitty-monitor (Oleada 2) |
| 2 | Procesos maliciosos | Nombres de procesos conocidos del atacante (ambas oleadas) |
| 3 | Archivos de carga útil | Archivos maliciosos conocidos por nombre y hash SHA-256 (4 hashes) |
| 4 | Hooks de Claude Code | Hooks inyectados en .claude/settings.json + heurística genérica de SessionStart |
| 5 | Tareas de VS Code | Tareas inyectadas en .vscode/tasks.json + heurística genérica de runOn: folderOpen |
| 6 | GitHub Actions | toJSON(secrets) en cualquier flujo de trabajo + advertencia de pull_request_target |
| 7 | Archivos lock de npm | Versiones de paquetes comprometidos en archivos lock |
| 8 | optionalDependencies | @tanstack/setup y @antv/setup maliciosos + 4 SHAs de commits impostores |
| 9 | Conexiones de red | Conexiones activas a infraestructura C2 (5 dominios/IPs) |
| 10 | Caché DNS | Resolución previa de dominios del atacante (4 dominios) |
| 11 | Ramas de Git | Patrón de nombres de ramas del atacante con temática de Dune |
| 12 | Scripts de ciclo de vida | Heurística: bun run en preinstall/postinstall (paquetes instalados) |
| 13 | C2 de buzón muerto | Palabra clave firedalazer y marcadores "Shai-Hulud" en el historial de git |
| 14 | Dependencias de GitHub | Heurística: dependencias github: fijadas a un SHA de commit en optionalDeps |
| Paquete | Versiones maliciosas | Primera versión segura |
|---|
@tanstack/react-router | 1.169.5, 1.169.8 | 1.169.9 |
@tanstack/router-core | 1.169.5, 1.169.8 | 1.169.9 |
@tanstack/vue-router | 1.169.5, 1.169.8 | 1.169.9 |
@tanstack/solid-router | 1.169.5, 1.169.8 | 1.169.9 |
@tanstack/react-start | 1.167.68, 1.167.71 | 1.167.72 |
@tanstack/router-plugin | 1.167.38, 1.167.41 | 1.167.42 |
timeago.js |
| 1.15M |
Crea un script de política de actualización: Crea un scripts/safe-update.sh que:
npm view <pkg> time --json)npm install <pkg>@latest --save-exactNo modifiques ningún código de aplicación. Solo toca archivos de configuración, .npmrc, scripts de package.json y configuración de CI.
.gitignore para evitar que .claude/settings.local.json se añada (debe permanecer local).VS Code (.vscode/):
.vscode/tasks.json y .vscode/launch.json en busca de tareas que ejecuten scripts o binarios inesperados.setup.mjs, router_runtime.js u otros nombres que no pertenezcan a este proyecto..vscode/extensions.json en busca de extensiones que no reconozcas.Cursor (.cursor/):
.cursor/settings.json y cualquier archivo de reglas en busca de comandos o hooks inyectados..vscode/.General:
preinstall, postinstall, prepare o prestart en package.json que no hayas escrito. Señala los sospechosos..github/workflows/ en busca de cualquier flujo de trabajo que use pull_request_target — márcalo como riesgo de seguridad con un comentario explicando por qué..gitignore excluya archivos de sesión del agente que podrían filtrar credenciales (.claude/projects/, .cursor/logs/, etc.).Informa lo que encontraste y lo que cambiaste. No modifiques código de aplicación.
Añade StepSecurity Harden-Runner como primer paso en cada trabajo: step-security/harden-runner@v2 con egress-policy: audit (o block si conoces tus endpoints permitidos).
Revisa secretos en los registros del flujo de trabajo: Asegúrate de que ningún paso del flujo de trabajo imprima ${{ secrets.* }} o ${{ toJSON(secrets) }} en stdout.
Informa todos los cambios. No modifiques código de aplicación.