El 11 de mayo de 2026, entre las 19:20 y 19:26 UTC — seis minutos — un atacante publicó 84 artefactos npm maliciosos en 42 paquetes del namespace @tanstack, todos firmados con la identidad legítima del pipeline de release de TanStack. Esos seis minutos abrieron la peor crisis de supply chain del ecosistema npm en 2026: más de 170 paquetes comprometidos, 404 versiones maliciosas, y la primera vez en la historia que un paquete malicioso lleva una SLSA provenance válida. Si tu app usa @tanstack/react-router, @tanstack/react-query, el SDK oficial de Mistral AI o cualquiera de los 65 paquetes de UiPath, este post es la guía de respuesta inmediata.
El ataque, bautizado Mini Shai-Hulud por su parecido con la campaña original de septiembre de 2025, no robó credenciales del mantenedor. Hizo algo más sutil y más peligroso: secuestró el runner de GitHub Actions a mitad del workflow oficial, después de que el OIDC ya había firmado la identidad. Para el registry de npm, los paquetes maliciosos fueron publicados por TanStack, no por un atacante. Las defensas tradicionales — 2FA, rotación de tokens, hardware keys — no protegen contra esto. Te explicamos qué pasó, cómo verificar si estás afectado, y qué cambia ahora en la forma de proteger una pipeline de release.
Qué pasó exactamente
La cronología pública, reconstruida a partir de los reportes de Snyk, Wiz y StepSecurity:
- Reconocimiento. El atacante (atribuido al grupo TeamPCP por StepSecurity) forkeó el repo
TanStack/routeren GitHub y estudió el workflow de release. - Trigger del workflow. Abrió un pull request que ejecuta el workflow
pull_request_target— un trigger que corre con permisos del repo original, no del fork. - Cache poisoning. El PR malicioso envenenó la caché de GitHub Actions con un
pnpm storemodificado, conteniendo dependencias troyanizadas. - Ejecución legítima del release. Cuando el mantenedor de TanStack ejecutó el workflow de release oficial — usando OIDC trusted publishing, la “mejor práctica” recomendada por GitHub y npm — el runner restauró la caché envenenada y publicó los paquetes con todas las firmas legítimas.
- Worm phase. Una vez instalados los paquetes maliciosos, el postinstall script intentó propagarse: leer tokens de npm del entorno y publicar versiones maliciosas de paquetes del mantenedor afectado.
El punto que hace este ataque histórico es el paso 4. Cualquier validador automático — npm audit, GitHub provenance verify, Snyk, Socket — ve un paquete legítimo. La firma SLSA es válida. El publisher es el correcto. No hay forma técnica de distinguir el paquete malicioso del legítimo desde el lado del consumidor. La detección llegó por análisis manual del código después de que un usuario notó comportamiento raro.
Paquetes confirmados como comprometidos
La lista completa supera los 170. Estos son los de mayor impacto por descargas semanales:
| Paquete | Versiones maliciosas | Descargas semanales | Acción |
|---|---|---|---|
@tanstack/react-router | 1.114.30 a 1.114.34 | 12.7M | Pinear a 1.114.29 o subir a 1.114.50+ |
@tanstack/router-core | 1.114.30 a 1.114.34 | 13M+ | Mismo rango |
@tanstack/react-query | 5.62.10 a 5.62.13 | 12M+ | Pinear a 5.62.9 o subir a 5.62.30+ |
@mistralai/mistralai | 1.4.0 a 1.4.2 | 240K | Subir a 1.4.10+ |
@uipath/sdk | 8.x corruptos | Variable | Verificar con UiPath security advisory |
opensearch | versiones de mayo 12 | 1.3M | Subir a la versión post-incidente |
guardrails-ai (PyPI) | 0.5.x | 80K | Revertir a 0.4.x o subir |
Lista completa actualizada en el aviso de Snyk y en el repo público de Wiz. Si tu CI corrió npm install o pnpm install entre el 11 y el 13 de mayo de 2026 sobre cualquiera de estos paquetes sin lockfile pineado, asumí que estás comprometido hasta probar lo contrario.
Cómo verificar si tu proyecto está afectado
Tres niveles de verificación, en orden de urgencia:
Paso 1: detectar versiones maliciosas en tu lockfile
npm ls @tanstack/react-router @tanstack/router-core @tanstack/react-query @mistralai/mistralai
Si el output muestra cualquier versión dentro de los rangos comprometidos de la tabla anterior, tenés contaminación local.
Para repos con pnpm o yarn:
pnpm why @tanstack/react-router
yarn why @tanstack/react-router
Paso 2: revisar tu pipeline de CI
Lo más importante: si tu pipeline ejecutó npm install durante la ventana del ataque sobre uno de los paquetes afectados, los secretos del CI quedaron expuestos. Lista mínima a rotar:
NPM_TOKENGITHUB_TOKEN(los que el workflow tuvo acceso, no el default ephemeral)- Cualquier variable de entorno con prefijo común (
AWS_*,STRIPE_*,DATABASE_URL, claves de Anthropic / OpenAI / Mistral) - SSH keys montadas en el runner
GitHub publicó una guía oficial de rotación post-incidente — seguila al pie de la letra.
Paso 3: forensia del entorno local de developers
El payload del worm intentaba persistir en el equipo del developer que instalara los paquetes. Si un dev de tu equipo corrió npm install con uno de los paquetes afectados:
ls -la ~/.npmrc ~/.npm-init.js ~/.bashrc.d/ 2>/dev/null
crontab -l 2>/dev/null
Buscá referencias a binarios que no instalaste vos, jobs cron sospechosos, o líneas extra en archivos de shell. El “destructive daemon” del payload — diseñado para borrar $HOME en caso de detección — fue desactivado a las 48 horas del descubrimiento, pero la persistencia (no la destrucción) puede seguir activa.
Por qué el OIDC trusted publishing falló
GitHub y npm habían empujado “trusted publishing” como la solución definitiva al problema de tokens robados. La idea: en vez de que el mantenedor guarde un NPM_TOKEN en GitHub Secrets, npm valida la identidad del runner de GitHub Actions vía OIDC y le permite publicar sin token persistente. Si el atacante no compromete el repo, no puede publicar.
El ataque de Mini Shai-Hulud demuestra el agujero conceptual: OIDC verifica la identidad del runner, no la integridad del workflow. Si el atacante puede influir en lo que el runner ejecuta — vía cache poisoning, vía dependencias intermediarias, vía cualquier paso que se ejecute antes del npm publish — el OIDC sigue firmando, porque la identidad del runner sigue siendo legítima. La firma final dice “esto fue publicado por el workflow X del repo Y”, lo cual es cierto, pero el contenido fue inyectado por el atacante.
La consecuencia práctica: trusted publishing es necesario pero no suficiente. Tu pipeline también necesita:
- Pin de versiones de cada acción (incluyendo SHAs, no tags) —
actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29, no@v4. - Cache desactivado o estrictamente validado en workflows de release.
- Trigger restringido a tags firmados con GPG, no a PRs ni a branches arbitrarias.
- Aislamiento del runner — los workflows de release deberían correr en un runner self-hosted distinto al de CI normal, o en GitHub Actions con
runs-on: ubuntu-latestpero permission scopes mínimos. - Auditoría humana del diff antes del release para releases ≥ 1.0.0 de cualquier paquete con más de 1M de descargas semanales.
Acciones inmediatas para tu equipo en LatAm
Si tu equipo o tu cliente usa Next.js, React, Astro o cualquier stack moderno de JavaScript, hay 70% de probabilidad de que tengas TanStack en el dependency graph aunque no lo hayas instalado directamente — react-query es transitividad común. Las cinco acciones que recomendamos correr hoy mismo:
npm audit --productionen todos los proyectos activos. Si aparece algo del listado, no mergees nada hasta tener un fix.- Forzar
--frozen-lockfileo--prefer-offlineen todos los workflows de CI hasta nueva orden. Esto evita quenpm installlevante versiones nuevas no validadas. - Rotar secrets del CI si tu pipeline corrió entre el 11 y el 13 de mayo de 2026. No esperes “ver si pasó algo” — los secrets exfiltrados pueden tardar meses en usarse.
- Configurar Socket o Snyk como pre-commit hook. Detectan paquetes recién publicados con scripts postinstall sospechosos. No son perfectos pero suben mucho la barra.
- Pin de SHA en acciones de GitHub. No
@v4. Sí@a5ac7e51b41094c92402da3b24376905380afc29. Renovado manualmente con cada actualización validada.
Para clientes con productos en producción y compliance regulatorio (banca, salud, educación), añadir:
- Reporte al CSIRT institucional con la lista de paquetes vulnerables y la ventana de exposición.
- Documentación del incidente en el log de seguridad interno — la LOPDP ecuatoriana requiere notificar incidentes que afecten datos personales dentro de las 72 horas.
El problema sistémico que esto expone
Mini Shai-Hulud no es un evento aislado. Es la tercera generación de ataques de supply chain en npm contando Shai-Hulud original (sept 2025), event-stream (2018), y ua-parser-js (2021). El patrón es claro: cada generación encuentra una nueva capa de la pipeline que las defensas anteriores asumían segura.
La conclusión incómoda: el modelo actual de npm (publish-once-trust-forever, sin verificación independiente del contenido) está estructuralmente roto para paquetes de alto impacto. La solución a largo plazo probablemente sea alguna combinación de:
- Verificación reproducible: el consumidor reconstruye el paquete desde fuente y compara hashes. Solo viable para paquetes con builds determinísticos.
- Quórum de mantenedores: dos o más mantenedores firman cada release. Algo así como Maintainer Multi-Sig que NSF está incubando.
- Period de observación: registries que retienen paquetes nuevos 24-48 horas antes de marcarlos como “stable” para
npm installsin flag. Esto solo le sirve a usuarios pacientes.
Mientras tanto, el peso de la defensa cae sobre cada equipo individual. Es injusto y es la realidad. Si tu app maneja datos de usuarios — cualquier app, incluyendo las que parecen “no críticas” — tratá la pipeline de release con la misma seriedad que la pipeline de pagos. La diferencia con un breach por contraseña filtrada es que en este caso el atacante usa tu propia identidad como vector.
Casos análogos en el ecosistema LatAm
Aunque el ataque fue contra repositorios de Estados Unidos y Europa, las víctimas indirectas en LatAm son significativas. Un caso real que estamos viendo en clientes ecuatorianos:
- E-commerce con Next.js + TanStack Query: el equipo tenía
@tanstack/react-querysin pinear enpackage.json. El CI corriópnpm installel 12 de mayo a las 03:42 hora Ecuador (UTC-5), traje la versión maliciosa, y desplegó a producción. Los secrets del runner — incluida la credencial de la base de datos PostgreSQL en RDS — quedaron expuestos durante 8 horas hasta que el equipo se enteró del incidente y bloqueó el workflow. - App fintech con Mistral AI integrado: 12 horas de exposición. El
MISTRAL_API_KEYfue rotado al detectar el incidente; revisión de logs no mostró uso anómalo de la API, pero la incertidumbre obligó a auditar todas las transacciones procesadas durante la ventana.
Estos no son casos hipotéticos. Si tu equipo no tiene una respuesta para “¿qué hacemos cuando un paquete que ya está en producción resulta ser malicioso?”, este incidente es la motivación que faltaba para construir esa respuesta antes del próximo Shai-Hulud — porque va a haber un próximo.
Tabla resumen
| Pregunta | Respuesta corta |
|---|---|
| ¿Cuándo ocurrió? | 11 de mayo de 2026, 19:20-19:26 UTC |
| ¿Cuántos paquetes? | 170+ npm, 2 PyPI, 404 versiones maliciosas |
| ¿Grupo atribuido? | TeamPCP (según StepSecurity) |
| ¿Vector principal? | Cache poisoning de GitHub Actions vía pull_request_target |
| ¿OIDC trusted publishing falló? | Sí, primer caso documentado con SLSA provenance válida |
| ¿Cómo verificar? | npm ls sobre los paquetes de la tabla |
| ¿Qué rotar? | NPM_TOKEN, GITHUB_TOKEN, secrets del CI durante la ventana |
| ¿Lecciones? | Pin de SHA en acciones, cache desactivado en release workflows |
Preguntas frecuentes
¿Mi proyecto está afectado si no uso TanStack directamente?
¿Por qué OIDC trusted publishing no protegió contra este ataque?
¿Cómo rotar correctamente un NPM_TOKEN después del incidente?
¿Vale la pena migrar a Deno o Bun por seguridad después de esto?
¿Las herramientas como Snyk, Socket o Dependabot detectan este tipo de ataques?
¿Tengo que reportar este incidente al SRI o a alguna entidad ecuatoriana?
¿Qué pasa con apps móviles que usan React Native con TanStack Query?
¿Cómo me preparo para el próximo ataque de supply chain?
Azirgo
¿Listo para construir tu Producto Digital?
Sitios web, apps móviles, software a medida y soluciones blockchain. Cuéntanos qué tienes en mente y armamos un plan claro contigo.
- Cotización clara en 48 horas
- Equipo en Ecuador, atención en español
- Desde un MVP hasta un producto en producción