En esta página
- ¿Qué es la inyección por archivo de instrucciones?
- Los archivos que llevan autoridad de prompt de sistema
- Por qué el diálogo de confianza no es una frontera de seguridad
- Anatomía del ataque: un minuto cincuenta y uno
- Seis formas de envenenar un archivo de instrucciones
- 1. El repositorio que te pidieron clonar
- 2. Una pull request desde un fork
- 3. Un skill o un plugin de marketplace
- 4. Un cambio de configuración MCP
- 5. Un archivo de instrucciones vendorizado o transitivo
- 6. Tu propio repositorio, desde dentro
- Qué cubren los controles nativos y qué no
- Ocho controles que sí reducen el riesgo
- Donde se detienen los controles: los archivos de instrucciones son código que nadie revisa
- Preguntas frecuentes
- ¿Un archivo Markdown puede ejecutar código?
- ¿Es seguro subir un AGENTS.md o un CLAUDE.md a mi repositorio?
- ¿Me protege el diálogo de confianza del editor?
- ¿Qué archivos debería poner en revisión obligatoria?
- ¿Se puede detectar con grep?
- ¿Afecta también a Copilot y Cursor, o solo a Claude Code?
- ¿En qué se diferencia del slopsquatting?
- ¿Qué hago primero si creo que un agente siguió un archivo envenenado?

Una mañana de junio de 2026, un desarrollador clonó una prueba técnica y la abrió en su editor. El repositorio no traía malware. Ni script post-install, ni binario ofuscado, ni dependencia sospechosa. Lo que traía era un .cursor/rules, un CLAUDE.md, un README.md con comentarios HTML invisibles y un .cursor/mcp.json. Un minuto y cincuenta y un segundos después de que el agente leyera esos archivos, había volcado las credenciales de AWS del desarrollador, identificado la cuenta, leído la configuración de Kubernetes, enumerado el estado de Terraform, buscado secretos en el código y enviado todo fuera mediante una llamada a una tool MCP. Nadie escribió ninguno de esos comandos. Esto es la inyección por archivo de instrucciones, y es el ataque que la pull request no puede ver.
¿Qué es la inyección por archivo de instrucciones?
La inyección por archivo de instrucciones es un ataque de prompt injection indirecto en el que la carga útil vive en un archivo del repositorio que el agente de código carga como guía de proyecto de confianza, y no como entrada no fiable. El atacante nunca habla con el modelo. Hace un commit, y el agente lo lee en tu nombre, en tu máquina, con tus credenciales.
Conviene ser preciso sobre por qué esto es una clase distinta del prompt injection que ya todo el mundo conoce. La inyección indirecta clásica esconde instrucciones en contenido que el modelo va a buscar: una página web, un ticket de Jira, el cuerpo de una issue. Se supone que el modelo lo trata como datos, y el fallo es que a veces lo trata como instrucción. La inyección por archivo de instrucciones invierte el planteamiento. Estos archivos están diseñados para ser instrucciones. Cargarlos como política no es un bug, es la funcionalidad documentada. CLAUDE.md existe para que un repositorio pueda explicarle al agente cómo funciona el proyecto. AGENTS.md existe para que el agente recoja las convenciones sin que nadie se lo diga. Toda la propuesta de valor es que el agente obedece al archivo.
Así que la vulnerabilidad no es "el modelo confundió datos con instrucciones". La vulnerabilidad es que el archivo tiene autoridad y su autoría no se verifica. La Cloud Security Alliance lo dejó por escrito en su nota de investigación de marzo de 2026 sobre inyección vía README: estos archivos se cargan al arrancar la sesión y se tratan con un nivel de confianza que se aproxima a la autoridad del prompt de sistema, de modo que un adversario capaz de modificarlos controla de hecho la política de comportamiento del agente en todas las interacciones posteriores dentro de ese repositorio.
Una dependencia tiene que instalarse para hacerte daño. Un archivo de instrucciones solo tiene que leerse.
Esa asimetría es lo que hace el ataque barato. Los ataques a la supply chain de paquetes necesitan un registro, un cambio de versión, un paso de instalación y normalmente un script de ciclo de vida. La inyección por archivo de instrucciones necesita un archivo de texto y alguien que abra la carpeta. No hay nada que detectar en la instalación porque no se instala nada. No hay nada que atrapar en el grafo de dependencias porque ninguna dependencia cambió. Y muchas veces tampoco hay nada en el diff, porque en un clon nuevo no hay diff.
Los archivos que llevan autoridad de prompt de sistema
El primer movimiento defensivo es conocer tu propia superficie de instrucciones. La mayoría de los equipos la subestima por un factor de cinco, porque piensa en "el CLAUDE.md que escribimos" y se olvida del archivo de settings, la carpeta de skills, la configuración MCP y las sobrescrituras por subdirectorio.
| Agente | Archivos que se cargan como instrucción o política | Comportamiento de carga |
|---|---|---|
| Claude Code | CLAUDE.md, .claude/settings.json (hooks), .claude/skills/*/SKILL.md, .claude/agents/*.md, configuración de los plugins instalados | La configuración de proyecto bajo .claude/ se carga en cuanto el directorio está aprobado |
| OpenAI Codex | AGENTS.md | La CLI recorre el árbol de directorios y carga cada AGENTS.md que encuentra |
| Gemini CLI y su sucesor Antigravity | GEMINI.md | Se descubre y se carga como memoria de proyecto de confianza |
| Cursor | .cursor/rules, .cursorrules (legacy), .cursor/mcp.json | Las reglas se aplican a los archivos que coinciden; la configuración MCP define qué tools existen |
| Cline | .clinerules | Se carga como reglas de proyecto para la sesión |
| GitHub Copilot | .github/copilot-instructions.md | Se antepone a las peticiones en ese repositorio |
| Windsurf | .windsurfrules y la carpeta .windsurf/rules | Se cargan como reglas del workspace |
| Todos los agentes, indirectamente | README.md, CONTRIBUTING.md, títulos de issues, descripciones de PR, comentarios de código, descripciones de dependencias, descripciones de tools MCP | Se leen en contexto durante el trabajo normal, nunca marcados como no fiables |
Dos filas merecen una segunda mirada.
La fila de .claude/settings.json no es una metáfora. Los hooks son comandos de shell que el agente ejecuta alrededor de sus propias llamadas a tools, y se definen en un archivo que vive en el repositorio. Por eso existe CVE-2025-59536: en Claude Code anterior a la versión 1.0.111, era posible ejecutar código antes de que el usuario aceptara el diálogo de confianza del arranque, mediante hooks de proyecto no fiables definidos en .claude/settings.json. Puntuación CVSS v4.0 de 8.7. El arreglo llegó en 1.0.111, y la lección sobrevivió al parche: un archivo JSON en un repositorio era una primitiva de ejecución remota de código porque el agente estaba diseñado para ejecutar lo que ese archivo declaraba.
La última fila es la que no deja de crecer. Cada superficie que un agente lee durante su trabajo ordinario es un canal candidato, y los investigadores encuentran nuevos sin parar. La Cloud Security Alliance documentó prompt injection llegando a claude-code-action a través de GitHub Actions, y la investigación GitInject, publicada en junio de 2026, catalogó casos reales de prompt injection en pipelines de CI/CD gobernados por IA. Si el agente lo lee, un atacante puede escribirlo.
Por qué el diálogo de confianza no es una frontera de seguridad
Todos los agentes serios muestran hoy una petición de consentimiento la primera vez que abres una carpeta desconocida. Es un control realmente útil, y también el peor entendido de la categoría, por lo que en realidad pregunta.
Pregunta si confías en el directorio. No dice nada, ni puede decirlo, sobre el contenido de los archivos de instrucciones que hay dentro. El consentimiento se concede con la granularidad de una carpeta y luego se aplica a una cantidad arbitraria de texto de política controlado por el atacante. Te hacen una pregunta, una sola vez, y la respondes antes de haber leído una sola regla.
La demostración más clara de esta brecha vino de Hookify, un plugin distribuido a través del marketplace oficial de Claude Code de Anthropic. Hookify es un motor de reglas: lee archivos de reglas del directorio del proyecto, expresados en Markdown con front matter YAML, y mete su contenido en el canal de mensajes de sistema de confianza del subsistema de hooks. Los investigadores de Pluto Security informaron de que un atacante que deje uno de esos archivos en un repositorio obtiene así un canal de dirección hacia el modelo, para cualquier usuario que tenga Hookify instalado y abra ese repositorio. Frente a Claude Opus 4.6, cinco cargas de comportamiento presentadas como inocuas convenciones de proyecto bastaron para que el modelo filtrara variables de entorno y secretos locales.
La respuesta de Anthropic es la parte que hay que interiorizar. El informe se cerró como Informative, working as designed: el diálogo de confianza del directorio es la frontera de seguridad, y una vez aceptado, la configuración de proyecto bajo .claude/, incluidos CLAUDE.md, los hooks de proyecto y la configuración de plugins como los archivos de reglas de Hookify, se carga de forma intencionada.
Esa respuesta se defiende en sus propios términos. Y es también un enunciado muy preciso del riesgo residual que ahora te pertenece.
Por eso también falla en la práctica el "basta con leer los archivos antes de aceptar". La superficie de instrucciones está repartida entre un archivo de settings, una carpeta de reglas, una convención Markdown por subdirectorio, una carpeta de skills y una configuración MCP. Las cargas se esconden en comentarios HTML que no renderizan nada. Y en cuanto clonas un monorepo, el árbol puede contener una docena de archivos de instrucciones anidados, y cualquiera de ellos puede sobrescribir a los de arriba.
Anatomía del ataque: un minuto cincuenta y uno
La prueba técnica envenenada que documentó Mitiga en junio de 2026 es el ejemplo público más limpio, porque las marcas de tiempo muestran exactamente el poco tiempo que tiene un humano para intervenir.
| Transcurrido | Lo que hizo el agente |
|---|---|
| 00:00 | Ingirió las instrucciones maliciosas de los archivos de configuración |
| 00:29 | cat ~/.aws/credentials |
| 00:42 | aws sts get-caller-identity, para identificar la cuenta |
| 00:58 | cat ~/.kube/config |
| 01:09 | Enumeró la infraestructura con comandos de Terraform |
| 01:30 | Buscó secretos en el código con grep |
| 01:51 | Exfiltró los datos recogidos mediante una llamada a una tool MCP |
Lee esa tabla como un ejercicio de respuesta a incidentes y el problema salta a la vista. La ventana entre la primera acción hostil y la exfiltración completa es de menos de dos minutos. No hay pull request. No hay build. No hay ningún artefacto que escanear. Todos los controles que viven aguas abajo del commit están mirando al sitio equivocado, porque el ataque terminó antes de que se escribiera una línea de código, y mucho antes de que se revisara.
Fíjate también en lo que el atacante no necesitó. Ningún zero-day. Ningún paquete malicioso. Ninguna cuenta de mantenedor comprometida. Necesitó una razón plausible para que clonaras un repositorio, que para cualquiera que esté contratando o buscando trabajo es la ingeniería social más fácil del sector.
Seis formas de envenenar un archivo de instrucciones
La prueba técnica es una vía de entrega. No es la parte interesante del modelo de amenaza, porque exige que clones algo nuevo. Estas son las vías que alcanzan repositorios en los que ya confías.
1. El repositorio que te pidieron clonar
Ejercicios de entrevista, reproducciones de bugs, "¿le puedes echar un ojo a esto?", repositorios de taller de conferencia, plantillas de arranque. Cualquier cosa que llegue con una razón legítima para lanzar un agente dentro. El caso de Mitiga es esta vía, y funciona porque la petición es auténtica y la carga es invisible.
2. Una pull request desde un fork
Es la vía que escala, porque alcanza tu repositorio sin ninguna ingeniería social. Si un workflow de agente corre con permisos de escritura en eventos originados en forks, la rama de un contribuidor puede añadir o modificar AGENTS.md, .clinerules o una carpeta de reglas, y el agente leerá la versión del atacante. La cadena Clinejection, divulgada públicamente el 9 de febrero de 2026 y documentada por Snyk, es la versión industrial de esto: prompt injection a través de títulos de issues convirtió el workflow de triaje automático de Cline en un vector de ataque a la supply chain, y un actor desconocido lo usó para publicar una versión no autorizada de la CLI de Cline en npm durante una ventana de ocho horas.
3. Un skill o un plugin de marketplace
Los skills de agente son archivos de instrucciones con un canal de distribución, que es la peor combinación posible. El estudio ToxicSkills de Snyk sobre el registro ClawHub encontró prompt injection en el 36 % de los skills analizados y catalogó 1.467 cargas maliciosas. Como los skills persisten entre sesiones una vez activados, una sola decisión de instalación sigue moldeando el comportamiento del agente de forma indefinida, en todos los repositorios que abras después. OWASP mantiene ya un Agentic Skills Top 10, lo que te dice a qué velocidad esto se ha convertido en una categoría propia.
4. Un cambio de configuración MCP
.cursor/mcp.json y sus equivalentes declaran qué tools existen y qué dicen sus descripciones. Cambia la configuración y cambias las acciones disponibles para el agente; cambia la descripción de una tool y cambias lo que el modelo entiende que hace esa acción. Es el mismo mecanismo del tool poisoning de MCP, que cubrimos en seguridad MCP y tool poisoning, llegando aquí por un archivo del repositorio en lugar de por un servidor.
5. Un archivo de instrucciones vendorizado o transitivo
Los archivos de instrucciones viajan. Un subárbol vendorizado, un submódulo de git, una plantilla generada, un directorio node_modules que el agente decide leer: cada uno puede traer su propio AGENTS.md. Como la mayoría de los agentes recorren el árbol y cargan lo que encuentran, un archivo anidado colocado en el fondo de una dependencia puede sobrescribir sin ruido las convenciones que escribiste en la raíz.
6. Tu propio repositorio, desde dentro
La vía menos espectacular y la más probable. Los archivos de instrucciones suelen escapar a la cultura de revisión que rodea al código fuente. No están en CODEOWNERS, no disparan ningún revisor obligatorio, y se leen como documentación. Cualquiera con acceso de escritura, incluida una cuenta de desarrollador comprometida o un contribuidor bienintencionado que copió una regla de un artículo, puede cambiar la política operativa de todos los agentes del equipo sin que un solo ojo de seguridad pase por el diff.
Qué cubren los controles nativos y qué no
Los fabricantes de agentes han entregado controles reales, y sería deshonesto insinuar lo contrario. Los sandbox limitan dónde caen las escrituras. Las escalas de aprobación crean puntos de control. Los valores de red por defecto están cerrados en varios modos cloud. Existen allowlists y deny lists de terminal. Antigravity incluye una allowlist de URL de navegador precisamente para cortar la vía de inyección por páginas recuperadas. Todo eso reduce el riesgo.
La brecha es más estrecha y más concreta que "los agentes no son seguros".
Dicho de forma sencilla: los controles hablan de capacidad, y la inyección por archivo de instrucciones habla de autoridad. El sandboxing responde a "qué puede tocar este proceso". No tiene nada que decir sobre "las instrucciones de quién está siguiendo el modelo". Son dos ejes ortogonales, y por eso un agente perfectamente aislado leerá encantado un archivo de credenciales y se lo pasará a una tool, si la política que cargó se lo pidió.
Es el mismo punto estructural que OWASP repite sobre los sistemas agénticos en producción, donde el prompt injection sigue siendo el principal motor de los fallos de seguridad en lugar de una categoría resuelta.
Ocho controles que sí reducen el riesgo
Nada de esto exige un fabricante nuevo. Casi todo es política y fontanería, y merece la pena hacerlo antes de comprar cualquier cosa.
Trata los archivos de instrucciones como código ejecutable
Añade AGENTS.md, CLAUDE.md, .clinerules, GEMINI.md, .cursor/**, .claude/**, .windsurf/** y .github/copilot-instructions.md al CODEOWNERS con un revisor de seguridad. Es exactamente la recomendación de la Cloud Security Alliance: someterlos a los mismos controles de revisión, aprobación y mínimo privilegio que cualquier ejecutable admitido en un repositorio.
Que el build falle cuando cambie la superficie de instrucciones
Un check de CI que liste las rutas modificadas y falle ante cualquier cambio de archivo de instrucciones sin aprobación de seguridad cuesta unas veinte líneas de YAML. Convierte una modificación de política invisible en una decisión visible.
Clona los repositorios desconocidos en un contenedor desechable
Mueve la frontera de confianza de la sesión a la máquina. Un dev container sin credenciales de cloud, sin kubeconfig y sin agente SSH convierte la cronología de Mitiga en seis comandos que fallan.
Deja al agente sin las credenciales que no necesita
Un agente que escribe CSS no necesita las claves de producción montadas en su entorno. Acota el .env que le das a cada sesión, mantén las credenciales de cloud de larga duración fuera del HOME del agente, y prefiere tokens cortos y con alcance limitado.
Prohíbe los verbos de exfiltración, no solo los destructivos
La mayoría de las deny lists se quedan en rm, sudo y git push. La exfiltración necesita una salida: curl, wget, nc, base64, y cualquier comando que imprima tu entorno. Añádelos, y mantén la red cerrada por defecto.
Sin auto-approve en código que no escribiste tú
El auto-approve para ejecución de shell y acceso al navegador es una comodidad razonable en un repositorio que es tuyo. Es la condición que habilita toda esta clase de ataque en un repositorio que no lo es. Mantén el ajuste por proyecto, no global.
Audita skills y plugins como si fueran paquetes
Fija versiones, desactiva la auto-actualización, lee el SKILL.md antes de activar, y mantén corto el conjunto activado. Recuerda que un skill activado para un proyecto sigue dirigiendo al agente en todos los proyectos siguientes.
Nunca un workflow de agente con escritura en eventos de fork
pull_request_target con permisos de escritura, más un agente que lee archivos del repositorio, es la forma de Clinejection. Separa el paso privilegiado del checkout no fiable, o no ejecutes el agente en forks.
Dos cosas que esta lista deliberadamente no dice. No te dice que dejes de usar archivos de instrucciones, porque son el mecanismo que hace útiles a los agentes sobre una base de código real y quitarlos equivale a hacer que el agente adivine. Y no te dice que leas cada archivo de reglas antes de aceptar un diálogo de confianza, porque ese consejo no sobrevive al contacto con un monorepo.
Donde se detienen los controles: los archivos de instrucciones son código que nadie revisa
Aplica los ocho controles de arriba y habrás cerrado las vías de entrega que ves. Lo que queda es el problema estructural, y es la razón por la que construimos CybeDefend como lo hicimos.
Un archivo de instrucciones es política ejecutable que ninguna parte de tu cadena de herramientas lee como código. Tu escáner SAST parsea código fuente; no parsea Markdown que reprograma un agente. Tu escáner de dependencias lee manifiestos; un archivo de reglas no tiene manifiesto. Tu escáner de secretos busca claves; esta carga no contiene ninguna. Y tu revisión de pull request, el lugar donde vive la seguridad de aplicaciones desde hace quince años, solo ve el cambio después de que un agente haya pasado una sesión obedeciéndolo. La cronología de Mitiga es la prueba: todo el incidente terminó 1 minuto y 51 segundos después de abrir una carpeta, es decir unas mil veces más rápido que el ciclo de revisión pensado para atraparlo.
Ese desfase de cadencia es la tesis de todo este sitio. La revisión de seguridad como puerta suponía un cuello de botella humano entre la intención y el código. Los agentes eliminaron el cuello de botella. Escribimos sobre la forma general del problema en seguridad de los agentes de código IA, y la inyección por archivo de instrucciones es su caso más afilado, porque aquí la carga del atacante y el manual operativo del agente son literalmente el mismo archivo.
Así que el control tiene que estar donde se toma la decisión, es decir dentro del bucle del agente y no aguas abajo.

En la práctica eso significa tres cosas para esta clase de ataque en concreto.
Tus reglas llegan con más autoridad que las del repositorio. VibeDefend se instala en el agente como servidor MCP más hooks, lo que significa que la política que recibe el modelo es la que escribió tu organización, no la que estaba commiteada en la carpeta. Un archivo del repositorio que le pide al agente leer ~/.aws/credentials ahora discute contra una regla que llegó antes.
El guardián actúa sobre la acción, no sobre el diff. Los hooks evalúan la llamada a la tool antes de que se ejecute. Leer un archivo de credenciales, mandar un volcado del entorno a curl, invocar una tool cuya descripción cambió desde ayer: son decisiones que el agente toma en plena sesión, y son el único sitio donde un control todavía puede decir no.
Los hallazgos están en el bucle, no en un dashboard. El agente tiene acceso en vivo a lo que nuestros escáneres encontraron en el código, las dependencias, los secretos, la infraestructura y los pipelines, así que cuando propone un cambio razona sobre el estado de seguridad real del repositorio en lugar de adivinar. Eso es también lo que le permite notar que el pipeline que le acaban de pedir modificar corre en eventos de fork con permisos de escritura.
Nada de esto elimina la necesidad de los ocho controles. Cambia lo que pasa en el hueco que no pueden cerrar, que son los noventa segundos entre abrir una carpeta y ver salir un secreto.
Preguntas frecuentes
¿Un archivo Markdown puede ejecutar código?
No por sí solo, y eso es lo que lo hace eficaz. El Markdown aporta las instrucciones; el agente aporta la ejecución. Si el agente tiene acceso a shell y auto-approve activado, un archivo de instrucciones es funcionalmente un script cuyo intérprete es el modelo. El único caso en que el archivo se acerca a una ejecución literal es un archivo de settings que declara hooks, que es lo que convirtió CVE-2025-59536 en una ejecución remota de código en Claude Code anterior a 1.0.111.
¿Es seguro subir un AGENTS.md o un CLAUDE.md a mi repositorio?
Sí, y deberías. El riesgo no es tenerlo, es que nadie sea su dueño. Pon el archivo en CODEOWNERS con un revisor de seguridad, exige revisión en los cambios, y audita las copias anidadas más abajo en el árbol. El problema es un archivo de instrucciones sin revisar; uno revisado es documentación que además configura tus agentes.
¿Me protege el diálogo de confianza del editor?
Protege el directorio, no el contenido. Anthropic enunció esta posición de forma explícita al cerrar el informe de Hookify: una vez aceptado el diálogo de confianza del directorio, la configuración de proyecto bajo .claude/, incluidos CLAUDE.md, los hooks de proyecto y los archivos de reglas de plugins, se carga de forma intencionada. Aceptar el diálogo eres tú respondiendo por los archivos de instrucciones, no el fabricante validándolos.
¿Qué archivos debería poner en revisión obligatoria?
Como mínimo: AGENTS.md, CLAUDE.md, GEMINI.md, .clinerules, .cursorrules, y las carpetas .cursor/, .claude/, .windsurf/ además de .github/copilot-instructions.md. Añade cualquier archivo de configuración MCP y cualquier SKILL.md del árbol. Luego lanza una búsqueda recursiva, porque las copias anidadas son las que se escapan.
¿Se puede detectar con grep?
En parte, y merece la pena. Busca comentarios HTML en el Markdown, caracteres Unicode de ancho cero y bidireccionales, blobs en base64, y los verbos que importan: credentials, ~/.aws, ~/.kube, curl, env, export. Lo que grep no puede juzgar es la intención, porque las cargas eficaces se leen como convenciones de proyecto normales. En la investigación de Hookify, cinco cargas presentadas como convenciones inocuas bastaron para provocar una fuga de secretos.
¿Afecta también a Copilot y Cursor, o solo a Claude Code?
A todos. El mecanismo es arquitectónico, no propio de un fabricante: todos los agentes mayoritarios tienen una convención de instrucciones a nivel de repositorio, y todos la cargan como guía de proyecto de confianza. Cubrimos las particularidades de cada uno en las guías de Claude Code, Cursor, GitHub Copilot, OpenAI Codex y Windsurf.
¿En qué se diferencia del slopsquatting?
El slopsquatting explota un nombre de dependencia alucinado para que una instalación descargue código del atacante, como explicamos en qué es el slopsquatting. La inyección por archivo de instrucciones no necesita instalación ni registro. Cambia lo que el agente intenta hacer, en vez del código que acaba en el árbol, y por eso el escaneo de dependencias es estructuralmente ciego a ella.
¿Qué hago primero si creo que un agente siguió un archivo envenenado?
Trátalo como un incidente de credenciales, no de código. Rota todo lo que el agente pudiera leer: claves de cloud, kubeconfig, tokens de proveedores, cualquier cosa que estuviera en el entorno. Luego recupera el transcript de la sesión del agente y lee las llamadas a tools en orden, porque es tu único registro fiable de lo que se ejecutó de verdad. Mira el diff solo después, ya que en los casos documentados no se había modificado ningún código.


