Puntos clave
- CVE-2026-111771 permitió a servidores MCP aceptar tokens de portador destinados a otros servicios debido a la falta de validación de audiencia (aud).
- Valide los reclamos aud e iss de RFC 7519 contra listas de permitidos estrictas en el servidor.
- Inspeccione cabeceras JWT y reclamos en un entorno de pruebas sin conexión en el navegador antes de conectar agentes externos.
Resumen Ejecutivo y Perfil de Amenaza
El 20 de octubre de 2026, la base de datos de avisos de seguridad de GitHub publicó CVE-2026-111771 (GHSA-rvq5-wwqv-78pq), identificando una vulnerabilidad crítica de delegación de autenticación en la implementación oficial TypeScript de Model Context Protocol (@modelcontextprotocol/sdk). Al ejecutar servidores MCP a través de transportes HTTP remotos (como Server-Sent Events), la autenticación aceptaba tokens válidos emitidos para otros servicios dentro del mismo ecosistema de identidad.
Anatomía de la Vulnerabilidad: Confused Deputy en Audiencia
Bajo RFC 7519 (JSON Web Token), el reclamo aud (Audiencia) identifica a los destinatarios previstos del token. En versiones vulnerables de @modelcontextprotocol/sdk, el transporte HTTP verificaba la firma y la fecha de expiración, pero omitía la comprobación estricta del campo aud.
Inspección de Tokens Localmente
Antes de aplicar parches, verifique los reclamos de sus tokens de prueba:
- Abra el Decodificador JWT y JWS de DevOmniTools.
- Pegue el token sin el prefijo
Bearer. - Compruebe que el campo
audcoincida exactamente con el URI de su servidor MCP.
El decodificador se ejecuta 100% en la memoria de su navegador, garantizando que ninguna credencial salga de su entorno local.
Código: Vulnerable vs Seguro
// ✅ CONFIGURACIÓN SEGURA: Validación estricta de audiencia y emisor
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
import jwt from "jsonwebtoken";
const MCP_RESOURCE_AUDIENCE = "https://mcp.company.internal/api/v1";
const TRUSTED_ISSUER = "https://auth.company.internal/";
app.get("/sse", (req, res) => {
const authHeader = req.headers.authorization;
if (!authHeader?.startsWith("Bearer ")) {
return res.status(401).json({ error: "Token Bearer ausente o inválido" });
}
const token = authHeader.substring(7);
try {
const decoded = jwt.verify(token, process.env.IDP_PUBLIC_KEY!, {
audience: MCP_RESOURCE_AUDIENCE,
issuer: TRUSTED_ISSUER,
algorithms: ["RS256", "ES256"],
});
req.user = decoded;
} catch (err) {
return res.status(403).json({ error: "Token rechazado por audiencia inválida" });
}
const transport = new SSEServerTransport("/messages", res);
server.connect(transport);
});- Cliente solicita token
- IDP emite JWT con aud específico
- Servidor MCP valida firma y aud
- Ejecución autorizada de herramientas
FAQ
¿Cuál es la causa raíz de CVE-2026-111771 en servidores MCP?
El transporte HTTP del SDK TypeScript de MCP verificaba firmas criptográficas pero no validaba estrictamente que el reclamo aud del JWT coincidiera con el URI del servidor MCP.
¿Cómo pueden los desarrolladores verificar si un token contiene la audiencia correcta?
Los desarrolladores pueden decodificar el payload JWT en el navegador usando el decodificador JWT de DevOmniTools sin enviar credenciales a servidores remotos.
¿Los servidores MCP basados en stdio están afectados?
No. Los servidores basados en stdio se comunican a través de entrada/salida estándar del sistema y no usan middleware de autenticación HTTP.
