← Alle Playbooks
Playbook· security

Cuando el repo de otro configura tu IA. El caso ChainDrop

En agosto de 2026 un gusano empezó a escribir hooks de arranque en los archivos de configuración de los agentes de IA. El disparador no es instalar, sino que tu herramienta arranque dentro del proyecto. Diez pasos para comprobar, reaccionar y blindarte a largo plazo, incluida la cuestión de en qué orden se limpia.

Esta Academy explica en muchos sitios cómo darle a tu IA contexto automáticamente al arrancar. Un hook que se dispara en cada sesión nueva es de lo más útil que hay en todo el montaje. En agosto de 2026 alguien usó ese mismo mecanismo como vía de propagación.

No es motivo para renunciar a los hooks. Es motivo para tratarlos como lo que son: código que se ejecuta sin preguntar. Este playbook cuenta qué pasó, cómo compruebas si te afecta, y en qué orden reaccionas. El orden es la parte interesante, porque ahí los especialistas no se ponen de acuerdo.

1. Qué pasó

El 4 de agosto de 2026 fue tomada la cuenta del responsable de dos paquetes npm muy extendidos, keyv y cacheable. El código introducido, llamado ChainDrop o Mini-Shai-Hulud según la fuente, se propagó solo en cuestión de horas: más de 400 paquetes en más de 1700 versiones. Elastic cifra el alcance afectado en más de 1300 millones de descargas al mes, keyv por sí solo en unos 600 millones.

Esas cifras describen alcance, no infecciones. No toda descarga es una máquina comprometida. Pero dicen a cuántos proyectos pudo llegar esto, y es un número grande.

La parte que aquí te afecta no es la parte de npm. El gusano escribe en las carpetas de proyecto infectadas una configuración de arranque para tus herramientas de IA. En concreto un hook de arranque en .claude/settings.json y una tarea en .vscode/tasks.json que se ejecuta al abrir la carpeta.

2. Por qué te alcanza aunque no instales nada

Este es el punto que más sorprende.

Cuando una función maliciosa está en el paso de instalación de un paquete, la defensa está clara: no instalas, no pasa nada. Con un hook de arranque en la configuración del proyecto es distinto. El disparador no es compilar, sino que tu herramienta arranque dentro del proyecto.

Dos vías separadas, y las dos necesitan algo más que "hacer clic en la carpeta":

El hook del agente se dispara al arrancar Claude Code en ese directorio. Ni npm install, ni compilación: el propio comando de arranque es el disparador. Ahora bien, en el primerísimo arranque en un directorio nuevo se interpone la pregunta de confianza, y esa sí es una barrera de verdad. En un proyecto que ya confirmaste una vez, después basta con claude, y el hook se ejecuta con él.

La tarea del editor cuelga de runOn: "folderOpen" en .vscode/tasks.json. Solo se ejecuta cuando coinciden dos cosas: la carpeta cuenta como de confianza (Workspace Trust) y las tareas automáticas están permitidas ahí. Son dos interruptores separados, con uno solo no basta.

La conclusión práctica sigue siendo la misma, solo que más precisa: quien crea que un proyecto ajeno es inofensivo mientras solo lo mire y no lo compile, se equivoca. En un proyecto que ya has autorizado alguna vez, basta con que arranque tu propia herramienta. En el editor son dos autorizaciones, y confiar en la carpeta solo quita la primera: las tareas automáticas tienen que estar permitidas además. Esa es la diferencia entre "puede pasar" y "me pasa a mí".

A eso se suma la propagación: con un token de acceso robado, el gusano reparte esos mismos hooks por hasta 50 ramas en cada repositorio al que llega. Una sola máquina comprometida puede sembrar así una organización entera de archivos de configuración preparados.

3. Qué busca

El recolector del código malicioso comprueba más de 300 patrones de credenciales. Y apunta por su nombre a los accesos de Anthropic, Claude, Codex, Cursor y Gemini.

Esa es la noticia de verdad en este incidente. Las credenciales de IA ya no son un botín secundario con el que un recolector se topa por casualidad, son un objetivo explícito. Si tienes una clave de API en un archivo de configuración, trátala a partir de ahora como la contraseña de tu banco.

4. La comprobación inmediata, cuatro revisiones

Entra en cada proyecto que hayas abierto en las últimas semanas y mira si hay archivos de configuración que no pusiste tú.

# ¿Hay una configuración de proyecto que no reconoces?
ls -la .claude/ .vscode/ 2>/dev/null

# ¿Qué contiene? Busca hooks y tareas que se disparen al arrancar.
# No olvides settings.local.json: es local al proyecto, suele estar en el
# .gitignore y puede contener hooks igual que el otro.
cat .claude/settings.json .claude/settings.local.json 2>/dev/null
cat .vscode/tasks.json 2>/dev/null

# ¿Quién tocó estos archivos y cuándo, en TODAS las ramas, no solo la actual?
# -p enseña además el CONTENIDO del cambio. Sin eso solo ves QUE alguien tocó
# algo, y un commit con un nombre plausible se te cuela sin llamar la atención.
git log --all -p --format='%h %an %ad %s' --date=short -- .claude/ .vscode/

# ¿Y hay algo ahí sin commitear?
# --ignored es clave aquí: .claude/ está en el .gitignore de muchos proyectos, y
# entonces una llamada normal a status informa tan campante de "nada que ver".
git status --short --untracked-files=all --ignored=matching -- .claude/ .vscode/

Lo que debería hacerte levantar la ceja: una entrada que al arrancar se descarga algo y lo ejecuta directamente. Una cadena larga con pinta de texto codificado. Un comando que llama a una dirección de internet que no tiene nada que ver con el proyecto.

La pregunta por el origen se plantea de forma distinta según el archivo. En los archivos compartidos (settings.json, tasks.json) la vara de medir es el historial del proyecto: lo que esté ahí y no se pueda encontrar como un cambio deliberado hay que revisarlo. Con settings.local.json eso no funciona, porque es local a propósito y normalmente justo NO está en Git. Ahí la vara de medir es tu propia memoria: ¿creaste tú ese hook? Si no, lo escribió ahí otra persona.

Los dos últimos comandos son los más importantes, y ahí --all no es un detalle. Sin ese flag solo ves el historial alcanzable desde donde estás ahora. Justo eso se perdería el reparto por hasta 50 ramas del paso 2: la rama en la que está el hook sería invisible, y la comprobación daría vía libre. %an te enseña además el autor, porque un commit a nombre de un desconocido ya es una señal por sí sola.

Un archivo de configuración que aparece en un commit cuyo mensaje habla de algo completamente distinto es una señal de alarma independientemente de lo que contenga.

Lo que estos comandos no cubren: las ramas que solo están en tu alojamiento de código y que nunca te has traído, además de los forks y los pull requests. Eso lo repasas en el navegador, y desde un dispositivo en el que confíes.

5. La discrepancia que tienes que conocer

Ahora la parte en la que vas a encontrar dos recomendaciones que se contradicen. Las dos vienen de analistas serios, y las dos tienen argumento.

Un bando (JFrog, Microsoft, Unit 42) dice: renueva las credenciales de inmediato. Es lo estándar ante cualquier fuga, cada minuto cuenta, una clave robada se usa.

El otro bando (SANS Internet Storm Center) describe un dispositivo de hombre muerto. El código malicioso instala un pequeño servicio que comprueba cada minuto el token robado. Cuando el token deja de ser válido, es decir justo en el momento en que tú lo revocas, ejecuta una respuesta controlada a distancia. Según esa lectura, revocar es el disparador de la siguiente fase. Por eso SANS recomienda: primero desconectar, luego limpiar, y después renovar.

La contradicción es real, y aquí no la resuelvo con un término medio. Cuando el campo no se pone de acuerdo, no recibes una receta limpia, recibes una decisión.

Qué abarca la discusión y qué no. Los dos bandos hablan de la máquina infectada. En una cosa sí coinciden, y es la más importante: puede que tus credenciales ya se hayan ido antes de que te dieras cuenta de nada. Un atacante que las tiene las usa desde su propia máquina. Le da exactamente igual si tu ordenador está conectado a la red.

Por eso "primero desconectar y luego decidir con calma" es falso, y aquí al principio lo tenía escrito así. El aislamiento solo protege de que salgan datos NUEVOS y de que el código malicioso reciba órdenes NUEVAS. No protege lo que ya se fue. Quien aplaza la revocación hasta terminar la limpieza le regala al atacante justo ese rato para tus repositorios, tus cuentas en la nube y tus pipelines.

El camino que junta las dos cosas:

  1. Sacar de la red la máquina afectada. Eso no lo discute nadie y son segundos.
  2. Y justo después revocar, pero desde otro dispositivo demostrablemente limpio. El móvil, un segundo ordenador, el ordenador de una compañera. La máquina infectada se queda offline mientras tanto.

Así el atacante pierde los accesos en el momento en que te das cuenta, y no horas después.

Qué pasa entonces con el dispositivo de hombre muerto, siendo honestos: no queda desactivado, solo aplazado. Un servicio sin red normalmente ni siquiera se entera de que el token ha sido revocado. El disparador sigue armado y espera a la siguiente conexión. Por eso el último paso en esta situación no es "volver a la red", es reinstalar la máquina.

Lo que no puedes hacer aquí: volver a conectar la máquina infectada a la red "solo un momento" para renovar las claves. Entonces las nuevas se van igual de rápido que las viejas.

6. El orden, si has encontrado algo

  1. Desconecta la red. Wifi fuera, cable fuera. Antes que cualquier otro paso, y la máquina se queda offline hasta el paso 6.
  2. Revoca todo desde un dispositivo limpio. Móvil o segundo ordenador. Claves de IA, tokens del alojamiento de código, accesos a la nube, sesiones activas. Todo lo que fuese alcanzable desde la máquina infectada, no solo lo evidente. Las claves nuevas las generas también allí, y no llegan a la máquina infectada hasta que esta vuelva a considerarse limpia.
  3. Preserva pruebas. Copia los archivos sospechosos a otro sitio antes de borrarlos. Sin ellos, luego no puedes decir qué pasó. Trata esa copia como contaminada: es material probatorio, no una copia de seguridad para restaurar.
  4. Mira qué se ha instalado por ahí. Borrar un hook de arranque no basta si al lado corre un servicio que lo vuelve a crear. Revisa los servicios de usuario de tu sistema y las entradas de arranque automático.
  5. Elimina los archivos de configuración y revierte el cambio en el proyecto, en todas las ramas, no solo en la que estás. Las ramas que no tienes en local las revisas en el alojamiento de código, en el navegador, desde el dispositivo limpio.
  6. Reinstalar la máquina antes de que vuelva a la red.

Por qué el paso 6 es tan duro. Borrar archivos de configuración y quitar los arranques automáticos visibles es contención, no prueba. Con un gusano que se propaga solo, recolecta credenciales a propósito y trae un dispositivo de hombre muerto, se añade una cosa más: el disparador nunca llegó a saltar mientras estabas sin red, está esperando. Reconectar tras una limpieza a mano le regala justo ese momento.

Por eso el camino fiable es reinstalar desde una imagen de confianza. Suena duro para un ordenador de trabajo, pero es el único estado en el que después sabes a qué atenerte. Quien no pueda o no quiera, sigue con un riesgo residual conocido y al menos debería hacerlo a sabiendas, en lugar de darlo por resuelto. En cualquier caso, las claves nuevas solo llegan a esa máquina cuando cuenta como limpia.

Si en el paso 4 te sientes inseguro, ese es el punto en el que ayuda profesional sale más barata que adivinar. Un sistema medio limpiado es peor que uno del que sabes que está infectado, porque dejas de mirar.

7. La cuestión de npm, también sin resolver

Un segundo punto en el que las fuentes difieren. JFrog escribe que con las versiones más nuevas de npm los scripts ya no se ejecutan por defecto al instalar, así que ahí el código malicioso no se dispara durante la instalación. Microsoft describe la ejecución como el caso normal.

Los dos pueden tener razón, porque depende de tu entorno. Pero el número de versión por sí solo no responde a la pregunta. Lo que cuenta es la configuración que está realmente en vigor, y esa puede venir de la configuración global, de un .npmrc en el proyecto o de una variable de entorno. Así que pregunta por la configuración misma, no por la versión:

npm config get ignore-scripts

Si ahí pone false, los scripts de instalación se ejecutan en tu máquina, tengas la versión de npm que tengas. Y aunque ponga true: no te fíes, escríbelo en la ejecución concreta.

npm ci --ignore-scripts

Pero sobre todo: eso solo protege un lado. Contra el hook de arranque del paso 2 esa configuración no sirve absolutamente de nada, porque no tiene nada que ver con npm. Son dos vías distintas, y aquí solo se toca una.

8. A largo plazo: trata los hooks como código

La consecuencia de verdad no es el gusano concreto, es una costumbre.

Un archivo de configuración que ejecuta comandos al arrancar es código ejecutable. Solo que no lo parece, porque vive en una carpeta con un punto delante y nadie lo lee en la revisión. Justo por eso funciona el ataque.

Tres costumbres que lo corrigen:

Primera, .claude/settings.json, .claude/settings.local.json y .vscode/tasks.json merecen la misma atención que un archivo lleno de código. Cuando trabajas en el proyecto de otro, échales un vistazo a los tres antes de arrancar la herramienta.

Segunda, separa limpiamente los tres alcances. Está el personal y global (vale en todas partes, va en tu configuración de usuario), el compartido de todo el proyecto (.claude/settings.json, se versiona con el equipo) y el local al proyecto y personal (.claude/settings.local.json, se queda contigo). Un hook que solo necesitas tú y solo en este proyecto va en el tercer cajón, no en el global. Quien lo empuja a global lo deja corriendo a partir de ya en cada repositorio y agranda la superficie de ataque en lugar de reducirla.

Tercera, con proyectos ajenos sacados de internet vale la misma prudencia que con servidores MCP ajenos. Cómo se revisan esos está en Revisar servidores MCP ajenos con seguridad, y el procedimiento se traslada casi uno a uno.

9. Si trabajas en equipo

En un repositorio compartido, la configuración del proyecto es una superficie de ataque común. Quien puede cambiarla cambia las condiciones de arranque para todo el equipo.

Así que trata los cambios en esos archivos como cambios con revisión obligatoria. Nada de dejarlos pasar. Quien añade un hook de arranque escribe qué hace y por qué, igual que en cualquier otro cambio de código que corre en producción.

Si tus procesos corren automatizados, se añade una segunda capa: ahí el contenido ajeno se procesa a menudo sin filtrar. Es un tema propio, Claude Code en segundo plano entra en la mecánica.

10. La lección que queda

Un hook de arranque es útil precisamente porque corre sin preguntar. Justo por eso es un objetivo. Eso no es una debilidad de las herramientas, es la otra cara de la comodidad, y vale para cualquier automatismo que te montes.

La conclusión práctica es poco espectacular: mira una vez antes de abrir el proyecto de otro. Mantén tus credenciales fuera de los archivos que viajan con el proyecto. Y si algo arranca solo en algún sitio, ten claro qué hace.

Qué sigue

Si ahora vas a repasar tus hooks de todas formas, Depurar hooks cuando no se dispara nada es el vecino natural: los mismos archivos, en la otra dirección. Para el lado de las credenciales, Asegurar MCP sobre stdio es la entrada.

Una palabra sobre las copias de seguridad, porque aquí por una vez el orden es otro: Copia de seguridad de la memoria antes de actualizar trata las copias del caso normal, y ahí "asegurar primero, tocar después" es correcto. Ante una sospecha, no. Ahí toca: aislar primero, revocar desde el dispositivo limpio después, y solo entonces preservar pruebas, antes de cambiar nada en local. Una copia creada tras una posible infección es prueba, no punto de restauración. Para restaurar solo sirve un estado anterior al incidente. Quien confunde las dos cosas se saca el código malicioso de su propia copia de seguridad.

Source

A 9 de agosto de 2026. El incidente tiene cinco días y sigue bajo investigación, los detalles pueden cambiar. Las fuentes sobre los puntos de los pasos 5 y 7 siguen siendo contradictorias; este playbook deja la contradicción a la vista y saca de ahí una decisión de actuación prudente, en lugar de fingir que existe una receta unánime.

Cuando el repo de otro configura tu IA. El caso ChainDrop — StudioMeyer Academy