Google, JPMorgan y el Gobierno francés entregaron el mismo fallo MCP. Nadie preguntó quién controla el argumento

El lunes 5 de octubre, Ars Technica publicó una noticia con un titular que no pude pasar por alto: "MCP for agent-to-agent comms may be the riskiest protocol you've never heard of". Trabajo con el Model Context Protocol por los dos lados: expongo servidores MCP y ejecuto un cliente MCP que consume los de otros. Así que fui más allá del artículo, hasta el informe del investigador, los registros CVE y las pull requests que corrigieron los fallos. La historia es más útil ahí que en el titular.
El mismo fallo, cinco veces
El investigador es Syed Anas Mohiuddin, que se describe como independiente: sin empleador, sin laboratorio, sin equipo. Su actualización de octubre enumera cinco organizaciones cuyos propios equipos de seguridad confirmaron y corrigieron cada uno el mismo error: Google, JPMorgan Chase, Weaviate, la dirección interministerial digital de Francia (DINUM) y el gobierno de la ciudad de Tangerang, en Indonesia.
El error es la falsificación de peticiones del lado del servidor (SSRF). Una herramienta recibe un argumento, el argumento se convierte en una URL o una ruta, y el servidor lo va a buscar desde su propia posición de red sin comprobar dónde acaba realmente.
El caso de Google es el CVE-2026-14540, publicado el 31 de julio con Google como autoridad de numeración. Su MCP Toolbox, en las versiones de la 0.3.0 a la 1.4.0, construía su cliente HTTP sin política CheckRedirect y sin validación de la IP de destino, de modo que un parámetro de ruta manipulado podía hacerle seguir una redirección hacia un punto interno. La puntuación CVSS 4.0 es 8,0, High. La corrección, fusionada el 18 de junio, comprueba la dirección resuelta en el momento de la conexión para frenar el DNS rebinding, añade listas de IP permitidas y bloqueadas, y rechaza una URL base insegura al arrancar en lugar de en la primera petición.
El caso de JPMorgan es del que más aprendí. Su servidor MCP de documentación de pagos tenía dos herramientas que van a buscar contenido. Una, read_documentation, aplicaba una lista blanca de dominios. Su hermana, related(), iba a buscar cualquier URL que aportara quien llamaba. La pull request que lo corrigió el 18 de septiembre hace pasar las dos herramientas por una única vía de obtención "para que las dos herramientas no puedan volver a desincronizarse".
El caso francés muestra de dónde viene un mal valor: el servidor MCP oficial de data.gouv.fr iba a buscar la URL de una documentación del catálogo de datos abiertos, un campo que puede fijar cualquier productor de datos registrado. La corrección, fusionada el 4 de septiembre, valida la IP de destino en la conexión y vuelve a comprobar cada salto de redirección.
Rapid7 aporta un fallo distinto: el CVE-2026-97228, publicado el 25 de septiembre, una inyección GraphQL a través de un identificador de exportación sin validar en su servidor MCP Bulk Export, valorado en 2,7, Low, corregido en la 0.6.2. El propio aviso de Rapid7 nombra la exposición realista: "un cliente MCP anterior comprometido o descuidado, o una inyección de prompt indirecta que reenvía un identificador sin validar".
También presentó cinco informes sobre servidores MCP federales de Estados Unidos el 2 de septiembre. Siguen en triaje, así que los dejo fuera.
Por qué equipos que no comparten nada cometieron el mismo error
Su tesis cabe en una frase: "El desarrollador trata los datos que cruzan la frontera de MCP, en cualquier dirección, como de confianza porque vienen de dentro del sistema".
En un agente, eso falla. El argumento de una herramienta lo escribe un modelo que acaba de leer una página web, un documento o un correo que cualquiera pudo haber escrito. Douglas McKee, director de inteligencia de vulnerabilidades en Rapid7, dijo a Ars que todo lo que un LLM pasa a tu herramienta "debe tratarse como una entrada de un desconocido en Internet".
En la página Tools de la especificación actual de MCP, versión 2026-07-28, los requisitos de seguridad del lado del servidor son cuatro viñetas breves, que empiezan por "Validar todas las entradas de las herramientas". La guía detallada sobre SSRF (bloquear los rangos privados, validar cada destino de redirección, desconfiar del DNS rebinding, considerar un proxy de salida) está en la página Security Best Practices, y está escrita para las URL relacionadas con OAuth que un cliente MCP obtiene durante el descubrimiento de autorización. Si tu herramienta convierte un argumento en una URL, la mejor lista de comprobación de la especificación es una que tienes que trasladar tú mismo.
Protocol Pivoting, sin la receta
Sobre ese titular: en rigor, MCP conecta un agente con herramientas y datos, y A2A, un protocolo que Google inició y donó a la Linux Foundation, conecta agentes con otros agentes. Los despliegues reales encadenan los dos: un orquestador delega en agentes especializados por A2A, y cada especialista tiene sus propios servidores MCP.
El artículo de Mohiuddin de mayo llama Protocol Pivoting a la clase de ataque resultante. Un texto que controla el atacante llega en el resultado de una herramienta. El orquestador lo convierte en una tarea delegada. El especialista confía en su orquestador y actúa con sus propias credenciales y su propia posición de red. El host MCP validó la llamada a la herramienta, y A2A autenticó al orquestador. En palabras del artículo, "ninguna de las dos defensas a nivel de protocolo valida el contenido de la delegación entre protocolos". Es el viejo problema del confused deputy, con un agente en el papel del delegado.
No a todos les gusta el nombre nuevo. Markus Vervier, de X41 D-Sec, dijo a Ars que es inyección de prompt indirecta, y que el segundo protocolo "no es estrictamente necesario". En cuanto a la mecánica, estoy de acuerdo con él. El nombre sigue siendo útil, porque señala dónde va la corrección: no dentro de un protocolo, sino en el traspaso entre dos.
Lo que pregunto a cualquier stack MCP, el mío incluido
La LegalTech que construyo maneja documentos confidenciales, así que no voy a describir cómo está conectada. Aquí van, en cambio, las preguntas.
¿Quién controla cada argumento? Haz la lista de cada herramienta, cada argumento y la fuente de su valor: el usuario, el modelo o datos de origen. Todo lo que controla el modelo o los datos de origen es entrada de un desconocido. Si se convierte en una URL, un host o una ruta, hazla pasar por un único cliente HTTP vigilado: resolver y comprobar la IP en la conexión, sin redirecciones automáticas, una lista blanca de los hosts que la función necesita y un fallo duro al arrancar con una URL base incorrecta. Un solo cliente, para que una herramienta hermana escrita el próximo trimestre no pueda saltarse la comprobación.
¿Un identificador es un nombre o una llave? La especificación lo dice claramente en su guía sobre herramientas con estado: "un handle es un nombre, no una capacidad". Comprueba en cada llamada la autorización de quien llama contra él, y pásalo como variable enlazada, nunca por interpolación de cadenas, que es exactamente como Rapid7 corrigió su fallo.
¿Qué puede desencadenar el resultado de una herramienta? El resultado de una herramienta es un dato, no una delegación. Un contenido que llegó de fuera puede mostrarse o resumirse, pero no debería iniciar una escritura, una petición saliente o una tarea para otro agente en la misma ejecución sin que un humano o una política explícita digan que sí. La especificación ya dice que los clientes deberían mostrar al usuario las entradas de una herramienta antes de llamar a un servidor y mantener a un humano capaz de denegar las invocaciones. El artículo propone etiquetar cada fragmento de contexto con su origen y asociar los orígenes con las acciones permitidas. Un clasificador que detecte texto con forma de instrucción ayuda, pero en otros sitios uso un pequeño modelo juez para las decisiones de sí o no, y una probabilidad es un cable trampa, no un muro.
¿La delegación reduce el alcance? La especificación dice que los servidores MCP "NO DEBEN aceptar ningún token que no haya sido emitido explícitamente para el servidor MCP". La misma lógica debería valer entre agentes: un subagente que trabaja en una tarea delegada recibe lo que la tarea necesita, no todo lo que puede hacer su propia cuenta de servicio.
¿Qué acaba en tus logs? El segundo modo de fallo del informe no necesita ningún atacante: en un caso federal que sigue en triaje, un servidor registra los cuerpos completos de los errores de origen, que pueden contener datos personales. Con documentos confidenciales, es el fallo que buscaría primero.
El lunes
Abre tus servidores MCP y busca cada petición saliente. Para cada una, anota quién controla el destino. Si la respuesta es "el modelo" o "lo que devolvió el origen", tienes delante el fallo que cinco equipos sin relación entre sí entregaron este año.
La frase de McKee a Ars lo resume: "Cada pieza de esa cadena hizo exactamente lo que fue diseñada para hacer". MCP hace muy fácil exponer una función a un agente. Preguntar quién controla cada argumento sigue siendo nuestro trabajo.
Fuentes
- Ars Technica, "MCP for agent-to-agent comms may be the riskiest protocol you've never heard of" (5 de octubre de 2026)
- Syed Anas Mohiuddin, "Protocol Pivoting, four months later: the same MCP bug across a hyperscaler, a bank, a database company, and two governments" (octubre de 2026)
- Syed Anas Mohiuddin, "Protocol Pivoting: Cross-Protocol Attack Escalation in Agentic AI Systems" (24 de mayo de 2026)
- CVE Program, "CVE-2026-14540: Server-Side Request Forgery via Unrestricted HTTP Redirection in MCP Toolbox" (31 de julio de 2026)
- googleapis/mcp-toolbox, "fix(source/http): implement SSRF guard" (18 de junio de 2026)
- jpmorgan-payments/ai, "Fix SSRF: enforce domain allowlist in related() (RDI-159)" (18 de septiembre de 2026)
- datagouv/datagouv-mcp, "feat: harden SSRF on external APIs" (4 de septiembre de 2026)
- Rapid7, "CVE-2026-97228: Improper Neutralization of Special Elements in Data Query Logic" (25 de septiembre de 2026)
- Model Context Protocol, "Tools" (versión 2026-07-28)
- Model Context Protocol, "Security Best Practices" (versión 2026-07-28)
- A2A Protocol, "A2A Protocol" (consultado el 7 de octubre de 2026)
