Tu agente tiene dos entradas no confiables
Un programa tradicional tiene una frontera de confianza: la entrada que le entrega un usuario. Validas en ese borde y prácticamente has terminado. Un agente añadió en silencio dos más, y la mayoría de las herramientas construidas alrededor de los agentes solo trata una de ellas como real.
La primera entrada nueva es el código que escribe el modelo y que ejecuta tu proceso. La segunda es la salida de herramientas que lee el modelo y sobre la que después actúa. Ambas cruzan hacia tu sistema desde algún lugar que no controlas – la distribución de muestreo de un modelo de lenguaje, o el servidor de un tercero – y ambas se tratan como confiables en el momento en que llegan. La razón de que la seguridad de los agentes se sienta tan inestable ahora mismo es que la industria tiene una respuesta creíble para la primera entrada y sigue fingiendo que la segunda es el mismo problema. No lo es.
Puntos clave
- Los agentes tienen dos entradas no confiables, no una. Código generado por el modelo que tu runtime ejecuta, y salida de herramientas/servidores que tu modelo ingiere y sobre la que actúa. Fallan de maneras distintas y necesitan defensas distintas – confundirlas es la razón por la que la gente se siente en un sandbox mientras sigue siendo explotable.12
- La ejecución de código no confiable por fin tiene una respuesta de aislamiento creíble. El
micropython-wasmde Simon Willison ejecuta Python escrito por el modelo dentro de un sandbox de WebAssembly con límites de memoria y CPU y acceso controlado a archivos y red – las características que un sandbox real necesita, sobre un sustrato “probado en navegadores durante casi una década”.1 - El envenenamiento de herramientas no es un problema de ejecución de código, así que un sandbox de código no hace nada contra él. Las instrucciones maliciosas ocultas en la descripción de una herramienta MCP son “invisibles para los usuarios pero visibles para los modelos de IA”, y pueden secuestrar un agente aunque la herramienta envenenada nunca se ejecute.23
- El problema más profundo es una brecha de confianza entre el momento de la conexión y el tiempo de ejecución. Las descripciones de herramientas se revisan una vez, al aprobarlas; las respuestas de herramientas fluyen directamente al contexto del modelo sin ninguna comprobación equivalente – y un servidor malicioso puede cambiar la descripción después de que la aprobaste.2
Dos entradas, dos modos de fallo
Pon las dos entradas una junto a la otra, porque la asimetría es todo el asunto.
Cuando un modelo escribe código y tú lo ejecutas con exec(), el modo de fallo es el código le hace algo a tu máquina – lee un archivo que no debería, abre un socket, pone la CPU a girar para siempre, corrompe el estado. El radio de explosión es tu proceso y todo lo que puede alcanzar. La defensa es antigua y bien entendida: aislamiento. Ejecuta el código en algún lugar donde no pueda tocar lo que importa.
Cuando un modelo lee la salida de una herramienta y actúa sobre ella, el modo de fallo es las palabras cambian lo que el modelo decide hacer. Nada se ejecuta en tu host en el sentido clásico; en cambio, un texto que llegó como “dato” se interpreta como “instrucción”, y el agente – con tus credenciales en la mano – la cumple. El radio de explosión es todo lo que tu agente está autorizado a hacer. Ningún aislamiento de procesos ayuda, porque se suponía que el agente podía leer esa herramienta y actuar sobre ella. El exploit viaja por el camino legítimo.
Un sandbox de código es un muro alrededor de la primera entrada. Es necesario, y por fin está mejorando. También guarda un silencio absoluto sobre la segunda.
La entrada que por fin tiene un sandbox
El 6 de junio de 2026, Simon Willison publicó micropython-wasm, un paquete alfa para ejecutar Python en un sandbox de WebAssembly, tras años probando enfoques que nunca encajaban del todo.1 La motivación es exactamente la primera entrada no confiable: quiere ejecutar código generado por un LLM dentro de su Datasette Agent sin poner en riesgo el host, y como él lo dice, “un plugin defectuoso o malicioso podría romperlo todo o filtrar datos privados”.1
Lo que lo hace digno de atención es la lista de comprobación que realmente cumple, porque esa lista es la definición de un sandbox utilizable:
- Límites de memoria y CPU, para que un
while True: s += "x"escrito por el modelo no pueda agotar el host. La CPU se acota con el mecanismo de “fuel” de wasmtime – sobre el que Willison es honesto, señalando que las unidades son “difíciles de razonar”.1 - Acceso controlado a archivos y red, denegado por defecto en lugar de abierto por defecto.
- Un modelo de aislamiento limpio: el código se ejecuta en un hilo separado detrás de una cola de petición/respuesta, con el intérprete WASM bloqueado en una función del host hasta que se le entrega trabajo – así que el código no confiable nunca comparte el espacio de direcciones del host.1
- Un sustrato con trayectoria. Eligió WebAssembly porque fue “diseñado desde el principio para soportar todas las características que me importan y ha sido probado en navegadores durante casi una década”, y MicroPython porque Pyodide, orientado al navegador, no está soportado del lado del servidor.1
La honestidad es la marca del buen trabajo de seguridad. Willison lo publica como alfa y escribe que “no está listo para recomendárselo a nadie que no esté dispuesto a asumir un riesgo significativo”.1 Esa es la postura de la puerta de la evidencia – afirmar exactamente lo que has verificado y nada más. El punto no es que este paquete en concreto sea la respuesta; es que la forma de la respuesta para el código no confiable ya es clara y reproducible: una frontera de aislamiento real con límites de recursos y E/S denegadas por defecto. La primera entrada se está convirtiendo en un problema de ingeniería resuelto.
La trampa es creer que resolverlo te deja a salvo.
La entrada que no lo tiene
La segunda entrada no ejecuta código, así que el muro no hace nada. El 1 de abril de 2025, Invariant Labs reveló el ataque de envenenamiento de herramientas: “se incrustan instrucciones maliciosas dentro de las descripciones de herramientas MCP que son invisibles para los usuarios pero visibles para los modelos de IA”.2 La asimetría es el exploit – “los modelos de IA ven las descripciones completas de las herramientas, incluidas las instrucciones ocultas, mientras que los usuarios normalmente solo ven versiones simplificadas en su interfaz”.2 Una herramienta que en la interfaz dice “suma dos números” puede llevar, en la descripción que el modelo consume de verdad, una instrucción para leer ~/.ssh/id_rsa y exfiltrarlo a través de un parámetro oculto.2 OWASP ya lo cataloga como una clase de ataque con nombre.3
Dos propiedades lo vuelven dañino de una manera que el aislamiento no puede alcanzar:
Se dispara sin que la herramienta sea llamada. Las instrucciones envenenadas viven en la descripción, que el modelo ingiere cuando considera el conjunto de herramientas – así que el ataque puede aterrizar aunque la función nunca se ejecute.3 No hay ningún evento de código que meter en un sandbox.
La confianza se concede una vez y se abusa de ella después. Las descripciones de herramientas se revisan en el momento de la conexión, cuando apruebas un servidor. Las respuestas fluyen luego directamente al contexto del modelo en tiempo de ejecución sin ninguna comprobación equivalente – y, en el hallazgo del “rug pull” de Invariant, “un servidor malicioso puede cambiar la descripción de la herramienta después de que el cliente ya la haya aprobado”.2 Tu aprobación única no asegura nada continuo.
La demostración canónica no es hipotética. Unos investigadores envenenaron una issue de GitHub con texto inyectado; cuando un desarrollador pidió a su asistente que revisara las issues abiertas, el agente ingirió la issue, siguió las instrucciones ocultas, usó el token del desarrollador para leer repositorios privados y filtró el contenido en una pull request pública.3 Cada acción individual estaba autorizada. El agente hizo exactamente aquello para lo que sirve un agente. Por eso un sandbox de código es irrelevante aquí – nada no confiable se ejecutó; un texto no confiable simplemente fue ascendido a instrucción dentro de un proceso que tiene credenciales reales. Es la misma lección que Ken Thompson dejó en Reflections on Trusting Trust: el peligro no es el código que inspeccionas, es la confianza que extiendes sin inspeccionar.
Defender la segunda entrada
Si el aislamiento es la defensa para el código, la defensa para la salida de herramientas es tratar la frontera entre dato e instrucción como real, en tiempo de ejecución, cada vez – justo lo que el modelo de aprobación en la conexión se salta. La propia guía de Microsoft sobre MCP aterriza en el mismo lugar, recomendando “prompt shields” que detecten y filtren instrucciones inyectadas, más el spotlighting, donde “incluir delimitadores en el mensaje del sistema señala explícitamente la ubicación del texto de entrada” para que el modelo distinga contenido de comando.4 En concreto:
- Vuelve a comprobar las descripciones en tiempo de ejecución, no solo al aprobar. Fija la definición de herramienta que aprobaste y detecta cuándo la descripción de un servidor cambia debajo de ti. El rug pull solo funciona porque nadie mira dos veces.2
- Marca explícitamente la frontera dato/instrucción. Las respuestas de herramientas son datos, no directivas – y la versión práctica es el spotlighting: delimitar la salida de herramientas en el contexto para que al modelo se le diga, estructuralmente, que es contenido sobre el que razonar y no comandos que seguir.4 Se combina con la autorización a nivel de acción en las herramientas MCP para que ni siquiera un agente secuestrado pueda alcanzar las llamadas de alta consecuencia.
- Aplica el mínimo privilegio al camino autorizado. El exploit de GitHub funcionó porque un solo agente tenía a la vez “leer repos privados” y “abrir PR pública” – y el mínimo privilegio es exactamente lo que Microsoft nombra como higiene fundamental contra estos ataques.4 La seguridad por compartimentación de Joanna Rutkowska es el mismo instinto a nivel de arquitectura: asumir que un dominio está comprometido y asegurarse de que no pueda alcanzar los demás. Un agente que lee issues no debería ser el agente que tiene el camino de exfiltración.
- Vigila la salida, porque la exfiltración es el premio. La mayoría de estos ataques terminan en el mismo paso – datos que salen. Una vista de egreso silencioso atrapa la consecuencia incluso cuando la inyección se cuela por la puerta principal.
Nada de esto es un muro. Son puertas en un camino que el agente está destinado a recorrer – la clase de seguridad más difícil y menos satisfactoria, y la clase que la segunda entrada realmente requiere.
Lo que me llevo de esto
El modelo mental con el que me quedo es que “¿está mi agente en un sandbox?” es la pregunta equivocada, porque asume en silencio que hay una sola frontera que defender. Hay dos. El código que escribe mi modelo necesita un muro – y gracias a trabajos como el de Willison, construir ese muro se está volviendo una tarea normal de ingeniería con una especificación clara. La salida de herramientas que lee mi modelo necesita algo completamente distinto: un runtime que nunca deje que un dato se convierta en silencio en una instrucción, y un modelo de autorización tan ajustado que un agente secuestrado siga sin poder hacer gran cosa. Confundirlos es como terminas sintiéndote protegido – “mira, el código corre en WASM” – mientras sigues abierto de par en par por la entrada a la que nadie le puso una puerta.
La continuidad más profunda es que los agentes no inventaron tanto una nueva categoría de vulnerabilidad como nuevos lugares donde vive una antigua. La entrada no confiable siempre ha sido la raíz de la seguridad; la era de los agentes solo le dio dos puertas nuevas – una que puedes cerrar con aislamiento, otra que solo puedes vigilar con disciplina. Construye el muro y la puerta. Un muro solo, en un sistema con dos entradas, es media defensa que se siente como una entera.
Preguntas frecuentes
¿Cuáles son las dos entradas no confiables de un agente de IA?
Código generado por el modelo que tu runtime ejecuta, y salida de herramientas o servidores que tu modelo lee y sobre la que después actúa. La primera puede dañar el host directamente; la segunda puede secuestrar las decisiones del agente usando las credenciales y permisos que el agente ya tiene. Requieren defensas distintas – aislamiento para el código, separación dato/instrucción en tiempo de ejecución y autorización estricta para la salida de herramientas.12
¿Un sandbox de código protege contra el envenenamiento de herramientas MCP?
No. El envenenamiento de herramientas no ejecuta código en tu host – incrusta en la descripción de una herramienta instrucciones que el modelo trata como confiables, y puede dispararse aunque la herramienta nunca sea llamada.23 Un sandbox aísla la ejecución, así que no hace nada contra un ataque que viaja por las acciones legítimas y autorizadas del agente.
¿Qué es un ataque de envenenamiento de herramientas?
Revelado por Invariant Labs en abril de 2025, es un ataque en el que “se incrustan instrucciones maliciosas dentro de las descripciones de herramientas MCP que son invisibles para los usuarios pero visibles para los modelos de IA”.2 Como el modelo ve la descripción completa mientras el usuario ve una etiqueta simplificada en la interfaz, unas instrucciones ocultas – por ejemplo, leer claves SSH y exfiltrarlas – pueden secuestrar el agente. OWASP ya lo rastrea como una clase de ataque con nombre.23
¿Qué es la brecha de confianza entre conexión y ejecución?
Las descripciones de herramientas se revisan una vez, cuando apruebas un servidor (momento de la conexión). Las respuestas de herramientas fluyen luego al contexto del modelo en tiempo de ejecución sin ninguna comprobación equivalente, y un servidor malicioso puede cambiar una descripción después de la aprobación (un “rug pull”).2 La solución es verificar en tiempo de ejecución, no solo al aprobar.
Fuentes
-
Simon Willison, “Running Python code in a sandbox with MicroPython and WASM,” simonwillison.net, 6 de junio de 2026. Presenta el paquete alfa
micropython-wasmy el plugindatasette-agent-micropython; la motivación de que “un plugin defectuoso o malicioso podría romperlo todo o filtrar datos privados”; la lista de comprobación del sandbox (límites de memoria/CPU mediante el “fuel” de wasmtime, acceso controlado a archivos/red, aislamiento de petición/respuesta en hilo separado); el razonamiento de que WebAssembly fue “diseñado desde el principio para soportar todas las características que me importan y ha sido probado en navegadores durante casi una década”; y la advertencia de que “no está listo para recomendárselo a nadie que no esté dispuesto a asumir un riesgo significativo”. ↩↩↩↩↩↩↩↩↩ -
Luca Beurer-Kellner y Marc Fischer, “MCP Security Notification: Tool Poisoning Attacks,” Invariant Labs, 1 de abril de 2025. Revelación original: “Un ataque de envenenamiento de herramientas ocurre cuando se incrustan instrucciones maliciosas dentro de las descripciones de herramientas MCP que son invisibles para los usuarios pero visibles para los modelos de IA”; la brecha de visibilidad (“los modelos de IA ven las descripciones completas de las herramientas, incluidas las instrucciones ocultas, mientras que los usuarios normalmente solo ven versiones simplificadas en su interfaz”); el hallazgo del “rug pull” de que “un servidor malicioso puede cambiar la descripción de la herramienta después de que el cliente ya la haya aprobado”; y el ejemplo del
addenvenenado que lee~/.cursor/mcp.jsony~/.ssh/id_rsa. ↩↩↩↩↩↩↩↩↩↩↩↩↩ -
“MCP Tool Poisoning,” OWASP Foundation. Cataloga el envenenamiento de herramientas como una clase de ataque con nombre: instrucciones ocultas en los metadatos de herramientas que influyen en un agente “aunque la herramienta envenenada nunca sea invocada”, y el ejemplo de GitHub MCP en el que una issue envenenada lleva a un agente a leer repositorios privados mediante el token del desarrollador y a filtrarlos en una pull request pública. ↩↩↩↩↩↩
-
Sarah Young y Den Delimarsky, “Protecting against indirect prompt injection attacks in MCP,” Microsoft Developer Blog, 28 de abril de 2025. Recomienda “prompt shields” que “usan algoritmos avanzados de aprendizaje automático y procesamiento de lenguaje natural para detectar y filtrar instrucciones maliciosas”, el spotlighting donde “incluir delimitadores en el mensaje del sistema señala explícitamente la ubicación del texto de entrada”, la verificación de la cadena de suministro de los componentes MCP y una higiene fundamental como el mínimo privilegio. ↩↩↩