FlawOpen

flawopen.com/AI Security/mcp-typescript-sdk-bearer-token-audience-validation

● CWE-863 · CVSS 6.8 · Media
Investigación · FlawOpen

El SDK TypeScript de MCP no validaba el público de los tokens bearer

GHSA-rvq5-wwqv-78pq afecta a servidores HTTP MCP que aceptan tokens sin comprobar su público. Actualice y habilite expectedResource; devuelva el público verificado en AuthInfo.resource.[1]

💡 Explicación en Lenguaje Sencillo (ELI5)

Un guardia acepta una credencial válida, pero no comprueba para qué edificio sirve. Si una misma entidad emite credenciales para varios edificios, puede aceptar una destinada al edificio vecino. El servidor MCP debe comparar el destino de la credencial con su propia URL de recurso.[1]

Conceptos Clave y Términos

Público (`aud`)
El recurso o servicio para el que se emitió un token de acceso. Una firma válida o una introspección correcta no demuestra que el token estuviera destinado a este servidor MCP.[1], [7]
`expectedResource`
Opción que se habilita en el middleware corregido. Compara la URL de recurso configurada con el recurso que informa el verificador del token; si no coinciden, responde HTTP 401.[1], [2], [7]
`AuthInfo.resource`
URL del recurso que el verificador obtiene de datos confiables de validación o introspección. El middleware corregido necesita este valor; si falta, rechaza las solicitudes cuando se activa la comprobación.[1], [2], [7]
Paquetes afectados
El aviso incluye @modelcontextprotocol/sdk 1.6.0–1.31.0, @modelcontextprotocol/server 2.0.0–2.2.0, @modelcontextprotocol/express 2.0.0–2.0.1 y @modelcontextprotocol/server-legacy 2.0.0–2.3.0. No hay CVE asignado; el proveedor clasifica el fallo como CWE-863.[1], [3], [6]

Mapeos de marcos

  • Referencia CWE para la debilidad descrita en esta guía: CWE-863

Flujo de Ataque Paso a Paso

Paso 1

Un emisor presta servicio a varias API

La implementación afectada usa autenticación bearer HTTP para MCP y su servidor de autorización emite tokens para más de un servicio. Un token para otra API puede tener firma y vigencia correctas.[1]

Paso 2

Se valida el token, pero no su destino

En la integración afectada, requireBearerAuth() / verifyBearerToken() no incluían una comprobación del recurso esperado. Si verifyAccessToken() tampoco comprobaba aud, el servidor MCP podía aceptar un token destinado a otro servicio.[1], [2], [5]

Paso 3

El token de otro servicio llega a la autorización MCP

Un solicitante con un token válido para otro servicio puede quedar autenticado ante este servidor MCP. El aviso asigna CVSS 3.1 6,8 y CWE-863; no documenta un incidente concreto en explotación.[1], [4]

Paso 4

Actualice y vincule la validación al recurso MCP

Use la versión corregida, configure expectedResource con el identificador de este servidor y haga que verifyAccessToken() devuelva el público verificado como AuthInfo.resource. Actualizar no activa la opción; sin resource, todas las solicitudes reciben 401.[1], [2], [5], [3], [6], [7]

Paquetes y versiones afectados

PaqueteVersiones afectadasVersión corregida
@modelcontextprotocol/sdk1.6.0 a 1.31.01.32.0 o posterior
@modelcontextprotocol/server2.0.0 a 2.2.02.3.0 o posterior
@modelcontextprotocol/express2.0.0 a 2.0.12.0.2 o posterior
@modelcontextprotocol/server-legacy2.0.0 a 2.3.02.3.1 o posterior
Cualquier paquete con validación propia de aud en verifyAccessToken()La aplicación quizá ya implemente la comprobación que falta en el helper.Comprueba que la comparación sea estricta y use el identificador de recurso previsto.

Código Fuente: Vulnerable vs. Seguro

El ejemplo sigue el formato documentado por el SDK y la corrección incorporada. verifyJwt representa el validador JWT o la llamada de introspección que ya tenga la aplicación. Antes del arreglo, el middleware no ofrecía expectedResource ni comparaba la audiencia; la versión corregida compara el recurso configurado con AuthInfo.resource. Use el identificador exacto que el servidor de autorización incluye en aud; el ejemplo selecciona una URL de audiencia del mismo origen y deja que el SDK compare el recurso completo. Actualice el SDK 1.x a 1.32.0 o posterior; en 2.x use @modelcontextprotocol/server 2.3.0 o posterior. Con Express, actualice también @modelcontextprotocol/express a 2.0.2 o posterior. Como AuthInfo.resource es una URL, un valor aud simple que no sea una URL no se puede comparar mediante expectedResource: valide estrictamente ese identificador dentro de verifyAccessToken() y deje expectedResource sin configurar en ese despliegue. La implementación de verifyJwt es propia de la aplicación y se omite; no se muestra falsificación de tokens ni un procedimiento de explotación.[1], [2], [5], [3], [6], [7]

IMPLEMENTACIÓN VULNERABLE
import { requireBearerAuth } from '@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js';

const mcpServerUrl = new URL('https://api.example.com/mcp');
const auth = requireBearerAuth({
  verifier: {
    async verifyAccessToken(token) {
      const payload = await verifyJwt(token); // Verificación JWT de la aplicación
      return {
        token,
        clientId: payload.sub,
        scopes: payload.scopes,
        expiresAt: payload.exp,
        // No se devuelve ningún recurso y el helper afectado no tenía la opción expectedResource.
      };
    },
  },
});
PARCHE SEGURO Y ROBUSTO
import { requireBearerAuth } from '@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js';

const mcpServerUrl = new URL('https://api.example.com/mcp');
const auth = requireBearerAuth({
  verifier: {
    async verifyAccessToken(token) {
      const payload = await verifyJwt(token); // Verificación JWT de la aplicación
      // aud puede ser una cadena, una lista o no estar presente. Indica el recurso de este servidor.
      const audience = [payload.aud ?? []].flat().find(
        aud => URL.canParse(aud) && new URL(aud).origin === mcpServerUrl.origin,
      );
      const resource = audience ? new URL(audience) : undefined;
      return {
        token,
        clientId: payload.sub,
        scopes: payload.scopes,
        expiresAt: payload.exp,
        resource,
      };
    },
  },
  expectedResource: mcpServerUrl,
});

Lista de Verificación de Seguridad para Ingeniería

Fuentes

← AI Security Directory →