La prompt injection no es una petición mal formada que se pueda borrar con una expresión regular. Es un fallo de la frontera de confianza: un contenido que debía tratarse como dato cambia el comportamiento de un modelo de lenguaje. En un agente de IA, ese cambio puede convertirse en una llamada a una herramienta, un mensaje, una escritura de archivo o una petición a otro servicio. El Model Context Protocol (MCP) facilita descubrir y llamar herramientas, pero también da al texto no confiable más caminos hacia el modelo y los sistemas privilegiados.
Este artículo aplica OWASP GenAI LLM Top 10 2026 a agentes que leen contenido externo y usan MCP. Es un modelo de amenazas y una guía de ingeniería, no una auditoría de seguridad. Ningún control descrito garantiza seguridad. Hay que suponer que una inyección influirá a veces en el modelo y hacer que la acción resultante sea limitada, visible, reversible y difícil de desviar.
Por qué el modelo no es una frontera de seguridad
Un LLM recibe las instrucciones del sistema, la petición del usuario, los documentos recuperados, las descripciones y respuestas de herramientas, el historial y la memoria dentro del mismo contexto. Los delimitadores y las etiquetas expresan una política de confianza, pero no crean aislamiento arquitectónico. El modelo puede interpretar mal una etiqueta, tomar una frase plausible de un documento como orden o combinar varias pistas inocentes en un plan peligroso.
OWASP LLM01:2026 describe prompt injection como el cambio de conducta provocado por entrada directa, contenido recuperado, salida de una herramienta, imagen, audio, vídeo, contexto intermedio o memoria persistente. La categoría se distingue de la divulgación de información sensible, la agencia excesiva y el manejo inseguro de salidas, aunque pueden encadenarse en un incidente. La inyección aporta influencia, la herramienta aporta privilegios, el secreto es el activo y una solicitud de red, URL o comando de shell puede ser el canal de exfiltración.
El modelo no debe guardar credenciales, decidir autorización ni ser el único validador de una operación que cambia el estado. Esas decisiones pertenecen al código determinista de la aplicación. Deje al modelo la interpretación y la planificación, y haga que el sistema que lo rodea imponga lo que realmente puede suceder.
Modelo de amenazas para un agente conectado a MCP
Empiece por el flujo real de datos, no por un diagrama que termine en el chat. Identifique usuario, proveedor del modelo, agente, cliente y servidores MCP, servidor de autorización, API, navegador, archivos, memoria, índice, registros y red de salida. Marque cada conexión como del usuario, organización, tercero, pública o desconocida.
Los atacantes pueden ser un sitio o remitente malicioso, un colaborador de ticket o repositorio, una dependencia o paquete MCP comprometido, un operador deshonesto o un ladrón de token o sesión. Un usuario legítimo puede pegar sin intención un documento con instrucciones para otra IA. Una base interna puede recibir datos desde un formulario público, una sincronización o una cuenta comprometida.
Enumere instrucciones, tokens, claves, datos personales, código, documentos, metadatos de nube, configuración, memoria y capacidades de enviar, borrar, comprar, desplegar o modificar. Anote qué se lee, escribe u observa desde fuera. Una herramienta de solo lectura puede filtrar datos hacia un destino hostil, y una notificación es crítica si acepta URL o cuerpo arbitrarios.
Escriba el invariante esperado para cada flujo: «resumir el ticket sin seguir sus instrucciones», «leer solo este repositorio», «redactar un correo pero no enviarlo sin aprobación». Defina también el fallo: un secreto en un argumento, un scope que excede la tarea, una escritura fuera del espacio de trabajo o un destino no permitido.
Una ficha de riesgo contiene cinco campos: superficie, propagación, codificación, privilegio y canal de impacto. La superficie puede ser chat, web, PDF, descripción MCP, respuesta o memoria. La propagación cruza pasos, sesiones o agentes. La codificación puede ser texto, HTML, Unicode invisible, idioma poco representado, imagen, audio u ofuscación. El privilegio es identidad y scopes en la ejecución. El canal produce la consecuencia.
Inyección directa e indirecta
La inyección directa entra por el camino visible del usuario. Alguien puede pedir al agente que ignore la tarea, revele instrucciones ocultas, ejecute un comando sin límites o use una herramienta fuera de contexto. También cuenta el usuario honesto que pega texto con una orden dirigida a una IA. Un jailbreak busca eludir las protecciones del modelo, pero no hace falta un jailbreak: ejecutar amablemente una instrucción falsa de reembolso ya viola la frontera de la aplicación.
La inyección indirecta llega en contenido que el usuario no proporcionó como instrucción. Una página puede pedir que se suba el contexto del agente. Un archivo adjunto puede pedir restablecer una contraseña. Un ticket puede ordenar buscar en un repositorio privado. El payload puede estar en una fila de base de datos, el título de una issue, un README, una imagen o una respuesta de herramienta. El usuario quizá nunca vea los bytes ocultos en HTML, metadatos, una sección contraída, una imagen o caracteres de ancho cero.
MCP amplía la superficie en dos sentidos. Un servidor publica nombres, descripciones, esquemas de entrada, recursos y prompts que el cliente coloca en el contexto. Una descripción envenenada puede pedir que se llame primero a otra herramienta, que se añada un secreto a un argumento o que se confíe en una URL del atacante. Después, el servidor devuelve un resultado que el modelo puede interpretar como una instrucción nueva y usar para una segunda llamada. Es envenenamiento de herramienta o inyección en la respuesta aunque los mensajes JSON-RPC sean correctos.
Trate los metadatos de herramientas como influencia ejecutable, no como documentación. Fije las versiones de los paquetes, verifique los servidores, revise descripciones y esquemas, compare lanzamientos e inventaríe las capacidades permitidas de cada servidor. Una firma confirma procedencia pero no demuestra que una versión sea inocua. También hay que revisar la implementación y su comportamiento de red.
De la influencia a la exfiltración
La prompt injection se convierte en fuga cuando une una fuente con un canal de impacto. La fuente puede ser una issue envenenada recuperada por el agente. El canal puede ser una petición HTTP, un correo, un comentario público, una invitación de calendario, una URL de imagen, un registro o un argumento de herramienta. El atacante no necesita acceso directo a los datos privados si el agente puede leerlos y comunicarse fuera.
Modele explícitamente la «tríada letal»: contenido no confiable, datos sensibles y un canal externo o que cambia el estado. Quitar una de las tres partes suele ser más fiable que reconocer cada frase maliciosa. Un agente de investigación puede navegar páginas públicas sin sesión y con red restringida. Un resumidor de documentos privados puede no tener red ni permiso de envío. Un redactor de correo puede preparar un borrador sin autorización para enviarlo.
El filtrado de salidas no basta. Un secreto puede salir en un campo JSON válido, un parámetro URL, un mensaje de diagnóstico, una imagen, espacios, Unicode o un correo aparentemente normal. Controle el destino y el flujo de información antes del canal de impacto. Oculte secretos en registros y trazas, y pase las peticiones salientes por un proxy que bloquee direcciones privadas, dominios desconocidos y métodos inesperados.
Autorización MCP y controles OAuth
En un servidor MCP HTTP protegido, separe los papeles. El servidor MCP es el resource server, el cliente pide acceso en nombre del propietario del recurso y el authorization server emite tokens. Siga la especificación de autorización de MCP y los requisitos OAuth correspondientes a la versión, en vez de inventar un flujo de proxy.
Vincule cada token al recurso MCP previsto. La especificación exige el URI canónico en resource para ambas solicitudes y que el servidor valide su destino. Use Authorization, nunca la cadena de consulta. No acepte ni reenvíe tokens de otros recursos. Para una API posterior use otro token. El passthrough destruye audiencia y auditoría y puede volver al servidor un proxy de exfiltración.
Proteja el código de autorización con PKCE, redirect URI registradas de forma exacta, HTTPS en producción y un state aleatorio de un solo uso. Un proxy que registra clientes dinámicamente debe obtener consentimiento para cada cliente antes de redirigir al servidor de terceros. Vincule el consentimiento al client ID y a los scopes solicitados. Una cookie genérica que diga «la aplicación ya tiene consentimiento» no es suficiente y permite un confused deputy.
Considere el descubrimiento como entrada del servidor, no configuración confiable. Permita esquemas y hosts aprobados, rechace javascript:, data: y file:. Contra SSRF bloquee rangos privados, loopback, link-local y cloud metadata, valide redirecciones y use un proxy de salida. No abra URL mediante un shell.
Use scopes progresivos. Empiece con descubrimiento y lectura, pida un scope exacto al necesitarlo y registre los subconjuntos con un identificador de correlación. Evite *, all y scopes globales. Los claims no reemplazan la autorización para cada herramienta y argumento. Tokens cortos, almacenamiento protegido y rotación de refresh tokens públicos limitan el robo.
Un servidor MCP local necesita otra frontera. El proceso puede tener los privilegios del cliente, leer archivos, usar la red y ejecutar comandos. Muestre el comando de arranque completo y sus argumentos antes de conectar. Prefiera stdio o IPC local protegido a HTTP sin autenticación. Ejecute el proceso en un sandbox o contenedor con mínimos permisos de archivos, red y procesos, y conceda directorios y destinos adicionales de forma explícita.
Defensa en profundidad
El mínimo privilegio reduce el radio de impacto. Dé a cada agente solo las herramientas de un flujo. Separe lectura, redacción, aprobación y confirmación. Use credenciales de corta duración y específicas de la operación en lugar de un token permanente del usuario. Vuelva a comprobar la autorización al ejecutar, porque el plan, la sesión, la descripción o el recurso pueden haber cambiado.
Una aprobación debe ser un punto real de política. Exíjala para enviar, borrar, publicar, pagar, cambiar permisos, desplegar, abrir una nueva clase de datos o contactar un nuevo destino. Muestre la acción exacta, argumentos, identidad, objetivo, campos enviados y efecto, no solo el resumen del modelo. Vuelva a calcular la vista previa y vincule el consentimiento a un hash de la operación para que un paso posterior no sustituya los argumentos. Limite las acciones de bajo riesgo sin enseñar a los revisores a aceptar ventanas opacas.
El aislamiento limita lo que alcanza una inyección exitosa. Separe tenants, sesiones y memorias. Un agente de navegación no debe recibir credenciales privadas. Para un agente de código, monte un espacio de trabajo estrecho, niegue la red por defecto y use una identidad separada para instalar paquetes. Combine aislamiento de proceso, archivos, red y navegador. Un contenedor no es una política completa: revise montajes, sockets, identidad, egress y rutas de escape.
La procedencia del contenido hace que las decisiones sean comprobables. Adjunte fuente, autor, hora de recuperación, integridad y clase de confianza a cada documento, descripción y resultado de herramienta. Conserve esos datos durante los resúmenes y traspasos. Presente lo externo como datos con un límite visible y la etiqueta «no es una instrucción». La etiqueta orienta al modelo, pero el código debe imponer los permisos. Elimine o normalice caracteres invisibles en las fronteras de entrada y salida, aceptando que otras formas de ataque siguen siendo posibles.
Valide la salida con código confiable mediante esquemas estrictos, herramientas permitidas, argumentos tipados, comprobaciones de URL y ruta, límites de tamaño y frecuencia y una máquina de estados. No convierta la opinión de un segundo modelo en autorización. Un crítico puede señalar conducta sospechosa, pero la decisión final debe ser determinista. Registre prompts, fuentes, versiones de metadatos, argumentos, decisiones, aprobaciones y respuestas sin almacenar secretos en bruto.
Evaluación adversarial y operación
Evalúe el ciclo completo del agente, no solo el prompt. Prepare casos de override directo, HTML oculto, correo citado, repositorio envenenado, descripción MCP maliciosa, respuesta que solicita una segunda llamada, memoria entre sesiones, payload multilingüe o codificado, caracteres invisibles, URL SSRF, audiencia incorrecta del token y sustitución después de aprobar. Incluya contenido legítimo parecido a un ataque para medir falsos positivos y cumplimiento de la tarea.
Pruebe con un atacante adaptativo que conozca clasificadores, etiquetas, esquemas y reglas. Varíe palabras, modalidad, orden, momento y destino. Un benchmark estático puede parecer excelente mientras existe otra ruta. Mida éxito de ataques, llamadas no autorizadas, bytes sensibles que llegan al canal, elevaciones de scope, exactitud de aprobaciones y tiempos de detección y revocación. Conserve regresiones después de cada cambio de modelo, prompt, servidor, política o dependencia. El guía de evaluación de agentes de IA puede documentar el programa.
Compare la arquitectura con production AI agent architecture. Los detalles de OAuth están en MCP server TypeScript con OAuth. Esta guía se centra en esos materiales relacionados y no sustituye un análisis del entorno concreto.
Lista para un incidente
Ante una sospecha, detenga el flujo y desactive la capacidad mínima que lo contenga. Conserve prompt, fuente, procedencia, metadatos y versión de la herramienta, argumentos, metadatos del token sin su valor, decisiones, aprobaciones, destinos y horas. Clasifique la vía como directa, indirecta, de herramienta o persistente en memoria. Busque el payload en otros tenants, índices, colas, registros y traspasos.
Revoque las credenciales que pudieron entrar en el contexto o los registros, invalide sesiones y renueve refresh tokens. Bloquee el destino y el servidor MCP afectado. Revise las API posteriores en busca de lecturas, escrituras, mensajes o grants OAuth no autorizados. Compruebe que los argumentos ejecutados coinciden con la vista previa aprobada.
Después de contener, elimine entradas envenenadas de memoria o búsqueda, restaure metadatos confiables y añada la ruta a pruebas de regresión. Registre qué vio el modelo, qué permitió la política, qué aprobó la persona y qué control falló. Avise a responsables de incidentes y privacidad si los datos cruzaron una frontera. Que un clasificador reconozca el texto después no vuelve inocuo el evento.
Lo que la protección no puede prometer
La prompt injection sigue evolucionando porque los modelos actuales no imponen una separación formal entre instrucciones y datos. Entrenamiento, clasificadores, delimitadores, procedencia, esquemas de salida y revisión humana reducen el riesgo, pero un atacante adaptativo puede cambiar palabras, codificación, orden o modalidad. La revisión humana puede fallar por fatiga o una vista previa engañosa. Un sandbox mal configurado o un paquete fijado también puede ser peligroso.
No es correcto afirmar que un agente es inmune. Sí se puede afirmar que un flujo definido tiene fronteras explícitas, capacidades mínimas, controles deterministas, decisiones observables, fallos probados y una respuesta preparada. Reevalúe el modelo cuando añada un servidor MCP, herramienta, memoria, modelo, fuente de datos o canal de salida. Este texto es una guía de ingeniería, no una certificación ni una auditoría de seguridad.
Fuentes
- OWASP GenAI LLM Top 10 2026
- Especificación de autorización MCP
- Buenas prácticas de seguridad MCP
- OpenAI: Designing AI agents to resist prompt injection
- OpenAI: Understanding prompt injections
- Anthropic: Trustworthy agents in practice
- Google Cloud: AI security and safety for MCP servers
- Microsoft: Protecting against prompt injection attacks