Saltar al contenido principal

El peor día de npm: un ataque, una filtración, cero confianza

Axios fue secuestrado para instalar un troyano. El código fuente de Claude Code se filtró por source maps. Mismo registro, mismo día — dos fallas que tu equipo debe entender.

El peor día de npm: un ataque, una filtración, cero confianza

Ricardo Argüello

Ricardo Argüello
Ricardo Argüello

CEO & Fundador

Desarrollo de Software 10 min de lectura

El 31 de marzo de 2026, alguien secuestró la cuenta npm del mantenedor de axios y publicó versiones que instalaban un troyano de acceso remoto a cualquiera que ejecutara npm install. Axios tiene ~100 millones de descargas semanales y está presente en ~80% de los entornos cloud.

Horas después — sin relación alguna — un investigador descubrió que Anthropic había publicado el código fuente completo de Claude Code, más de 512,000 líneas de TypeScript, porque un archivo source map quedó incluido en el paquete npm.

Escribí sobre ambos incidentes por separado y al final los junté en un solo artículo. No están conectados, pero lo que encontré al analizarlos me resultó más útil en conjunto que por separado.

El ataque a axios

Cerca de la medianoche UTC del 31 de marzo, Feross Aboukhadijeh de Socket.dev lanzó la alerta: axios@1.14.1 había incorporado plain-crypto-js@4.2.1, un paquete que no existía antes de ese día. Treinta y nueve minutos después, axios@0.30.4 siguió — el atacante envenenó ambas ramas (1.x y 0.x) para maximizar el radio de impacto.

Lo que pasó después fue sorprendentemente directo. El atacante secuestró la cuenta jasonsaayman — el mantenedor principal de axios — cambió el email a una dirección de Proton Mail, y publicó ambas versiones manualmente vía npm CLI. No a través de GitHub Actions, no a través del pipeline normal de release del proyecto. Directo al registro. La dependencia maliciosa nunca apareció en el repositorio de GitHub.

plain-crypto-js hacía una sola cosa: ejecutar un script postinstall que desplegaba un troyano multiplataforma.

PlataformaPayloadDisfraz
macOSBinario en /Library/Caches/com.apple.act.mondDemonio del sistema Apple
WindowsCopia de PowerShell en %PROGRAMDATA%\wt.exeWindows Terminal
LinuxScript Python en /tmp/ld.pyArchivo temporal

El dropper usaba codificación de doble capa — Base64 invertido más cifrado XOR — para evadir el análisis estático. Después de ejecutarse, se autodestruía: eliminaba setup.js, reemplazaba el package.json malicioso con un stub limpio mostrando la versión 4.2.0. Post-ejecución, npm list no mostraba nada sospechoso.

El escáner automatizado de Socket.dev detectó plain-crypto-js en 6 minutos tras su publicación. npm eliminó las versiones maliciosas en ~3 horas. Pero en esa ventana, el 3% de los entornos afectados ya había ejecutado el payload.

Si instalaste axios entre aproximadamente las 00:21 y 03:15 UTC del 31 de marzo y obtuviste las versiones afectadas, trata tu sistema como completamente comprometido. Rota cada credencial de esa máquina.

La filtración de 512,000 líneas de Claude Code

Horas después, el investigador de seguridad Chaofan Shou publicó un hallazgo que no tenía nada que ver con el ataque a axios pero todo que ver con npm.

El CLI de Claude Code de Anthropic — versión 2.1.88 — se publicó con un archivo source map de 57 MB que mapeaba el bundle de producción minificado de vuelta al código fuente original en TypeScript. Cualquiera que ejecutara npm pack o navegara el contenido del paquete podía leer todo el código de Anthropic en texto plano.

La escala: ~1,900 archivos, más de 512,000 líneas de TypeScript, ~40 herramientas integradas, ~50 comandos slash. Solo el motor de consultas principal eran 46,000 líneas. El sistema de definición de herramientas, 29,000 líneas.

Me pasé una hora leyendo el código filtrado. La arquitectura en sí es TypeScript bien organizado — nada escandaloso. Lo que me llamó la atención fue todo lo que venía junto con ella.

Todos los system prompts de Claude Code — las instrucciones completas que gobiernan cómo se comporta — estaban en un archivo JSON que npm sirve a cualquiera que lo pida. El hilo en Hacker News señaló un sistema basado en regex para detectar sentimiento negativo y palabras ofensivas en los prompts de los usuarios, que se registra en logs. Eso generó preguntas sobre qué más captura la telemetría.

Después vinieron las funciones no anunciadas. KAIROS es un modo de asistente persistente que siempre está activo, observa, registra y actúa proactivamente sobre lo que detecta — protegido detrás de feature flags de compilación y ausente de los builds públicos. Una familia de modelos “Capybara” apareció en el código, confirmando el nombre clave de la filtración de Mythos tres días antes. Y un comando /buddy activa una mascota virtual tipo Tamagotchi con especies, niveles de rareza, estadísticas y animaciones.

La que generó más debate fue un “modo encubierto” que elimina información de identificación de IA de los commits. Algunos lo vieron como una herramienta práctica; otros lo llamaron suplantación problemática de identidad por IA.

¿Cómo pasó? Claude Code usa el bundler de Bun, que genera source maps por defecto a menos que los desactives explícitamente. Alguien olvidó agregar *.map al .npmignore o configurar el bundler para omitir la generación de source maps en builds de producción. Según CyberSecurity News, esta es la segunda filtración similar de source maps de Anthropic — un incidente comparable ocurrió a principios de 2025.

No se comprometieron datos de usuarios. No hubo malware involucrado. Pero la arquitectura completa de herramientas, el sistema de permisos, los flujos de autenticación y la hoja de ruta de producto no anunciada de Anthropic son ahora públicos.

Qué conecta estos dos incidentes — y qué no

Cuando me senté a escribir sobre el ataque a axios, me di cuenta de que no podía ignorar la filtración de Claude Code pasando el mismo día. No porque los incidentes estén relacionados — no lo están. Pero después de más de 20 años revisando infraestructura de software — y ahora haciéndolo en IQ Source para clientes B2B en América Latina — sigo encontrando lo mismo: los equipos se preparan para un tipo de problema y dejan el otro completamente abierto.

El ataque a axios fue una cuenta comprometida: token npm de larga vida, sin MFA, y el atacante publicó directo al registro sin pasar por GitHub. Socket.dev lo detectó en 6 minutos — las herramientas para este tipo de amenaza existen y funcionan.

Con Claude Code la historia fue distinta. No hubo ningún atacante. Anthropic publicó su propio código fuente porque nadie revisó qué archivos iban en el paquete npm. Un source map de 57 MB. Ninguna herramienta de seguridad lo detectó porque técnicamente no era una amenaza — era un descuido. Lo encontró un investigador externo que estaba curioseando el registro.

Los equipos responsables ni siquiera se cruzan. El fortalecimiento de autenticación es trabajo del equipo de seguridad. La auditoría de artefactos del build es de DevOps. En la mayoría de las organizaciones, esos equipos no hablan entre sí sobre npm — y npm no distingue entre las amenazas. Es solo un registro, sirviendo paquetes sin importar si fueron comprometidos por un atacante o inflados por un archivo de depuración olvidado.

Los agentes de IA lo empeoraron

Andrej Karpathy publicó sobre su casi-incidente en cuestión de horas. Había instalado @googleworkspace/cli unos días antes, que trajo axios 1.13.5 — una versión antes de la release envenenada. Si lo hubiera instalado unas horas después, la dependencia no fijada habría resuelto a la versión comprometida.

Su observación fue la que quedó grabada: “No puedo sentir que estoy jugando ruleta rusa con cada pip install o npm install (que los LLMs también ejecutan libremente en mi nombre).”

Esa frase — “que los LLMs también ejecutan libremente en mi nombre” — merece su propia sección. Hace seis días, escribimos sobre cómo el ataque a LiteLLM rompió las cadenas de confianza de IA a nivel de dependencias. Pero el artículo de LiteLLM no cubrió qué pasa cuando los agentes de código con IA ejecutan npm install por su cuenta. Sin revisión de diffs. Resolviendo a la versión más reciente por defecto. A las 3 AM mientras duermes.

Múltiples respuestas en el hilo de Karpathy describieron el escenario exacto — “los flujos agénticos que auto-instalan dependencias sin fijar versiones son el peor caso. Comprometidos a velocidad de máquina sin nadie revisando el diff.” El riesgo no es solo que tu cadena de dependencias tenga eslabones débiles. Es que las herramientas de IA están acelerando a través de esos eslabones más rápido de lo que cualquier humano puede revisar.

Qué previene esto de verdad

Fijar dependencias por sí solo no habría prevenido ninguno de los dos incidentes. Los controles específicos que realmente los habrían detenido son diferentes para cada caso:

Contra el ataque a axios

El modelo de seguridad por defecto de pnpm. pnpm deshabilita los scripts postinstall por defecto para todos los paquetes excepto los explícitamente permitidos. Si los entornos afectados hubieran usado pnpm en lugar de npm, el dropper del troyano nunca se habría ejecutado — incluso con la versión comprometida instalada.

Procedencia SLSA. Las versiones maliciosas no tenían registro de procedencia porque se publicaron manualmente vía CLI, no a través del pipeline normal de GitHub Actions del proyecto. Si npm exigiera verificación de procedencia para paquetes populares, las versiones sin firmar habrían sido rechazadas al momento de instalar.

Restricciones de antigüedad mínima. Una política que rechace paquetes publicados en las últimas 72 horas habría dado tiempo a la comunidad para analizar antes de que alguien instalara. Socket.dev ya ofrece esto en su Socket Firewall.

Contra la filtración de Claude Code

npm pack --dry-run antes de cada publicación. Un comando que te muestra exactamente qué archivos se incluirán en el paquete. Si alguien en Anthropic hubiera ejecutado esto antes de publicar la versión 2.1.88, el archivo source map de 57 MB habría sido inmediatamente visible.

.npmignore explícito. Agrega *.map, *.map.js, y cualquier artefacto de depuración al .npmignore. No te apoyes en .gitignore — npm usa .npmignore si existe y recurre a .gitignore si no.

Configuración del bundler. Bun genera source maps por defecto. Para builds de producción, establece sourcemap: "none" explícitamente. No dejes los valores por defecto para artefactos de producción.

Verificación de publicación en CI/CD. Un paso previo a publicar que revise el tamaño total del paquete y señale archivos inesperados. Un source map de 57 MB en un paquete de herramienta CLI debería haber disparado una alerta antes de llegar al registro.

El cuarto incidente de Anthropic en seis semanas

Usamos Claude todos los días en IQ Source y construimos soluciones para nuestros clientes con él. Eso no cambia lo que cuatro incidentes en seis semanas dicen sobre la madurez operativa — y si estás evaluando proveedores de IA, este patrón debería estar en tu radar.

En seis semanas: Mrinank Sharma renunció citando preocupaciones de gobernanza interna. Anthropic eliminó su compromiso de pausa de la Política de Escalamiento Responsable. La filtración de Mythos expuso ~3,000 documentos internos por una mala configuración del CMS. Y ahora el código fuente completo de Claude Code publicado en npm por un error de configuración del build.

Cubrimos las implicaciones de confianza del proveedor en detalle hace tres días, y mantengo ese análisis. Hoy solo se agregó un cuarto dato. Si tu marco de evaluación de proveedores se sigue concentrando en benchmarks de modelos y certificaciones sin mirar el historial operativo del proveedor, estás ignorando el patrón.

Lo que cambiamos en IQ Source después de esto

Ejecutamos npm pack --dry-run en cada paquete que mantenemos antes del mediodía del 31 de marzo. Sin source maps, sin archivos .env, sin sorpresas. Eso tomó 15 minutos. Ya debería haber sido parte de nuestro CI — ahora lo es.

Después auditamos lockfiles de todos los proyectos activos de clientes. Buscamos tres cosas: paquetes con scripts postinstall que no habíamos revisado, dependencias no fijadas con rango caret en paquetes de alto tráfico, y pipelines de CI que resuelven la más reciente en vez de instalar desde un lockfile.

La primera verificación es sobre lo que consumes. La segunda es sobre lo que publicas. Si solo haces una, el 31 de marzo mostró qué pasa con la otra.

Sigo volviendo a algo que Karpathy escribió en una respuesta en ese hilo: “No puedo sentir que estoy jugando ruleta rusa con cada npm install.” Si tu equipo siente lo mismo — o si tienes agentes de IA haciendo la instalación por ti — envíanos tu package-lock.json a contacto. Te decimos en qué lado del 31 de marzo estás expuesto.

Preguntas Frecuentes

seguridad npm ataque cadena suministro axios Claude Code source maps gestión dependencias seguridad pipeline

Artículos Relacionados

Code review para humanos, pero 41% del código es IA
Desarrollo de Software
· 9 min de lectura

Code review para humanos, pero 41% del código es IA

El 41% del código en 2025 fue generado o asistido por IA, con 1.7x más defectos. Tu proceso de revisión asume que el autor entiende lo que escribió. Ya no.

calidad de código revisión de código código generado por IA
Lo que tu IA no pregunta (y tu startup va a pagar)
Desarrollo de Software
· 7 min de lectura

Lo que tu IA no pregunta (y tu startup va a pagar)

Un founder perdió $87,500 porque su IA generó código funcional sin cuestionar la seguridad. Las herramientas de IA responden lo que pides, no lo que falta.

vibe coding seguridad de software startups