# Una actualización de Dependabot publicó un gusano. 22 paquetes.

Published: 2026-09-17

Un bot abre una pull request. Un humano la fusiona 24 minutos después. 95 minutos después de eso, un gusano ha publicado 110 versiones maliciosas de sus 22 paquetes npm, bajo su nombre, con un token que encontró en su CI.

Canonical: https://thedailydiff.dev/es/video/2026-09-17-dependabot-tanstack/

## Qué cubre este vídeo

- Un bot, un humano, un gusano
- Cómo sucedió, por qué npm lo permitió, quién tiene la culpa
- Cronología: la caché envenenada
- 21:48 — la actualización de Dependabot
- Por qué funciona

## Capítulos

- 0:00 Un bot, un humano, un gusano
- 0:20 Cómo sucedió, por qué npm lo permitió, quién tiene la culpa
- 0:30 Cronología: la caché envenenada
- 1:15 21:48 — la actualización de Dependabot
- 1:50 Por qué funciona
- 2:20 git blame
- 2:45 Radio de impacto
- 3:00 Veredicto

## Transcripción traducida

Traducido de la narración original en inglés. El audio y los subtítulos disponibles están controlados por YouTube.

### Un bot, un humano, un gusano

0:00 Un bot abre una pull request; un humano la fusiona veinticuatro minutos después. Noventa y cinco minutos después, un gusano ha publicado ciento diez versiones de sus paquetes, como él. El post-mortem de TanStack tiene las marcas de tiempo upstream, el mantenedor downstream tiene el resto, y Hacker News le da mil cien puntos y un nombre: Mini Shai-Hulud. Cómo sucede, por qué npm lo permite, quién tiene la culpa.

### Cómo sucedió, por qué npm lo permitió, quién tiene la culpa

0:21 Esto es The Daily Diff, post-mortem. 11 de mayo, por la mañana. Una bifurcación renombrada abre una pull request contra TanStack Router. Se cierra en una hora, pero un flujo de trabajo de benchmark ya ha ejecutado su código y

### Cronología: la caché envenenada

0:33 ha guardado una caché envenenada bajo la clave que usará el flujo de trabajo de lanzamiento. Diecinueve-veinte. Una fusión legítima ejecuta el lanzamiento. La caché vuelve, un binario lee la memoria del runner, toma el token de publicación y envía ochenta y cuatro versiones en cuarenta y dos paquetes, con procedencia válida. Las pruebas fallan. Publica de todos modos. Diecinueve cuarenta y seis, un investigador de StepSecurity presenta el problema; a las nueve UTC todo está obsoleto y el aviso está fuera.

0:55 Obsoleto no es desaparecido: npm se niega a despublicar cualquier cosa con dependientes, así que permanece instalable durante horas. Veintiuno cuarenta y ocho. En un proyecto de datos de aviación de nueve estrellas, Dependabot abre su pull request rutinaria: actualizar el grupo de dev-dependencias, trece actualizaciones. Dos son versiones envenenadas de TanStack. Veintidós-doce: fusionado. El flujo de trabajo de publicación ejecuta npm C-I con el token en

### 21:48 — la actualización de Dependabot

1:15 alcance; un script de preparación lo lee, y a las veintidós-diecisiete el gusano publica como él. Cinco versiones de cada paquete al que llega el token, incluso un viejo proyecto paralelo: un token clásico para todo. Ciento diez versiones en noventa y cinco minutos. Se entera por correo electrónico, después de medianoche. Por qué funciona. Uno: npm install ejecuta scripts de ciclo de vida de extraños por defecto, y el script de preparación de una dependencia git cuenta.

1:39 Dos: el gusano quiere una cosa: un token que publique sin un segundo factor. Luego pregunta al registro qué más posee ese mantenedor, y lo republica todo consigo mismo dentro. Tres: nada en la cadena es una persona.

### Por qué funciona

1:51 Un bot propone, un pipeline instala, y el gusano devuelve el favor: sus ramas de entrega secreta se llaman dependabot slash github-actions slash fremen. git blame. El modelo de instalación de npm, cincuenta y cinco por ciento: los scripts se ejecutan al instalar, lo obsoleto permanece instalable, existen tokens de bypass de doble factor. El CI de TanStack, veinticinco: un flujo de trabajo de destino de pull request no auditado que ejecuta código de bifurcación con acceso de escritura a la caché. El hábito de actualización, quince: trece actualizaciones fusionadas en veinticuatro minutos, token en la habitación.

2:17 Dependabot, cinco: tan confiado que el gusano viste su uniforme.

### git blame

2:20 Radio de impacto: cuarenta y dos paquetes TanStack. Veintidós downstream, de un proyecto con nueve estrellas. Más de ciento sesenta en todo el ecosistema una vez que el gusano llega a Mistral. Cada versión upstream llevaba una firma válida: construida por el oficial pipeline. Verdadero. Veredicto, post-mortem: SHIP IT. Ambos mantenedores publican post-mortems con marcas de tiempo en un día; en tres, el pipeline downstream instala con ignore-scripts, divide la construcción de la publicación y elimina el token de larga duración.

### Radio de impacto

2:47 Los valores predeterminados de npm no se han movido. Lunes: ignore-scripts al instalar, y el token de publicación fuera del trabajo que lo ejecuta. Envíame el incidente del que todavía no se te permite hablar, en los comentarios, o en thedailydiff.dev. Y eso es el diff de hoy.

### Veredicto

3:00 Soy Niko de Axrisi. Fusiona responsablemente.

## Fuentes

- [TanStack postmortem (Tanner Linsley, May 11, refined May 15)](https://tanstack.com/blog/npm-supply-chain-compromise-postmortem) — tanstack.com
- [TanStack "Hardening TanStack After the npm Compromise" (May 12)](https://tanstack.com/blog/incident-followup) — tanstack.com
- [TanStack/router#7383 — the StepSecurity detection issue](https://github.com/TanStack/router/issues/7383) — github.com
- [Downstream incident post, @squawk/\* (May 12)](https://github.com/neilcochran/squawk/discussions/251) — github.com
- [Downstream hardening post (May 14)](https://github.com/neilcochran/squawk/discussions/264) — github.com
- [The Dependabot PR #246 (opened 21:48 UTC, merged 22:12)](https://github.com/neilcochran/squawk/pull/246) — github.com
- [@tan\_stack advisory post, 21:19 UTC](https://x.com/tan_stack/status/2053948103766716630) — x.com
- [StepSecurity — worm internals, bypass\_2fa search, Dependabot-style branch names](https://www.stepsecurity.io/blog/mini-shai-hulud-is-back-a-self-spreading-supply-chain-attack-hits-the-npm-ecosystem) — www.stepsecurity.io
- [Socket](https://socket.dev/blog/tanstack-npm-packages-compromised-mini-shai-hulud-supply-chain-attack) — socket.dev
- [Aikido — "over 160 packages, including Mistral"](https://www.aikido.dev/blog/mini-shai-hulud-is-back-tanstack-compromised) — www.aikido.dev
- [Hacker News (1,097 points)](https://news.ycombinator.com/item?id=48100706) — news.ycombinator.com
