VORVEX

CVE-2026-66908: el JWT era válido, pero no para tu API

La firma y la expiración eran correctas. Aun así, un token emitido para otro servicio podía superar la autenticación de Camel porque issuer y audience no se validaban.

Por Equipe Vorvex5 min de lectura

Un JWT con firma válida no es automáticamente válido para toda API que confía en esa clave. El token también debe haber sido emitido por la autoridad esperada y para la audiencia correcta. La CVE-2026-66908 muestra qué ocurre cuando esa segunda parte desaparece silenciosamente: Apache Camel aceptaba tokens destinados a otro servicio, siempre que no hubieran expirado y estuvieran firmados por una clave presente en el keystore configurado.

Este escenario es especialmente relevante en empresas que comparten un proveedor de identidad entre varias aplicaciones. El atacante no necesita falsificar una firma ni descubrir el secreto del JWT. Necesita obtener legítimamente un token aceptado por el mismo dominio de confianza y presentarlo a una API que debería rechazar ese emisor o esa audiencia.

Technical diagram showing a valid JWT issued for one application being accepted by a different Apache Camel API because issuer and audience validation are missing
La firma prueba que una clave confiable emitió el token. Sin validar issuer y audience, no prueba que el token pertenezca a esa API.

Qué confirma la CVE-2026-66908

Apache clasifica la falla como alta y CWE-287, autenticación impropia. El registro de NVD muestra un CVSS 3.1 de 7.5 atribuido a CISA-ADP, con vector AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N; NVD todavía no publicó una puntuación propia. El componente afectado es camel-platform-http-main, desde la versión 4.8.0 hasta antes de la 4.22.0. Tanto el servidor HTTP de la aplicación como el servidor de administración pasaban por la ruta vulnerable.

  • Precondición: autenticación JWT habilitada con un keystore y sin jwtIssuer ni jwtAudience
  • Lo que sí se validaba: firma y expiración del token
  • Lo que no se validaba: las claims iss y aud
  • Acceso necesario: red, sin credencial previa en la API objetivo
  • Versión con comportamiento fail closed: Apache Camel 4.22.0

Dónde desaparecía la validación

Según el advisory, JWTAuthenticationConfigurer.buildJwtOptions devolvía null cuando jwtIssuer y jwtAudience no estaban configurados. El código que lo llamaba omitía JWTAuthOptions.setJWTOptions, y Vert.x JWTAuth se construía solo con el keystore. El servidor arrancaba normalmente, sin advertir que la política aplicada era más permisiva de lo esperado. Las opciones de issuer y audience llegaron a la línea principal recién en la versión 4.21.0, por lo que versiones anteriores ni siquiera ofrecían ese control en este componente.

http
GET /orders HTTP/1.1
Host: api-b.example
Authorization: Bearer <unexpired-token-for-api-a-signed-by-a-trusted-key>
Accept: application/json
Formato de la verificación en un entorno autorizado. El token debe provenir del propio laboratorio y ser válido para otra audiencia; no es necesario alterar su firma, payload o algoritmo.

La prueba decisiva no consiste en enviar un token inválido. Consiste en comparar dos tokens legítimos firmados por una clave confiable: uno con aud correspondiente a la API y otro emitido para una audiencia diferente. En la configuración vulnerable, ambos podían superar la autenticación. Esto hace que el hallazgo sea fácil de perder en pruebas que solo verifican tokens expirados, firmas modificadas y algoritmos inseguros.

Split security diagram comparing complete JWT validation with signature expiry issuer and audience checks against incomplete validation that checks only signature and expiry
La validación completa vincula la credencial con el emisor y el recurso esperados. Verificar solo firma y expiración permite reutilizar el token fuera de su contexto.

La firma no reemplaza al contexto

La firma responde si el token fue modificado y si vino de una clave confiable. La claim iss identifica quién lo emitió; aud limita para qué recurso fue creado. En un proveedor multi-tenant o un keystore que confía en varias claves, omitir esas dos comparaciones amplía el conjunto de credenciales aceptadas. Incluso con un solo emisor corporativo, un token de una aplicación interna puede obtener acceso a otra API sin que el IdP haya autorizado ese uso.

  • Mapea todos los emisores y claves aceptados por el keystore, no solo el IdP nominal
  • Solicita tokens para dos audiencias controladas y compara la respuesta del mismo endpoint
  • Repite la prueba en el servidor de la aplicación y en el servidor de administración
  • Accede al backend por la ruta directa para confirmar que el gateway no sea la única capa que valida claims
  • Verifica si los logs internos de autenticación distinguen token expirado, firma inválida y audiencia incorrecta

Cómo hacer el triage sin explotar producción

La primera etapa puede ser completamente estática. Confirmamos la versión resuelta en el build y buscamos las propiedades de autenticación en archivos de aplicación, manifests y charts. El comando siguiente no envía tráfico ni manipula tokens. Revela si el componente está presente y si la configuración menciona los controles relevantes. Los secretos no deben copiarse al informe.

bash
./mvnw -q dependency:tree \
  -Dincludes=org.apache.camel:camel-platform-http-main

rg -n 'authenticationEnabled|jwtKeyStore|jwtIssuer|jwtAudience|jwtAllowMissingIssuerAndAudience' \
  src/main/resources deploy charts
Triage local y de solo lectura. Ajusta los directorios al repositorio y revisa valores sensibles sin imprimirlos en evidencias compartidas.

Después del triage, una prueba dinámica controlada debe usar tokens emitidos para el laboratorio y observar también la ruta directa hacia Camel. Si la validación de iss y aud existe solo en el API gateway, cualquier ruta interna, ingress alternativo o puerto de administración que evite el gateway reabre la falla de confianza.

La corrección exige atención a la línea de versión

La recomendación principal de Apache es actualizar a 4.22.0. En esa versión, el servidor se niega a iniciar con un keystore JWT cuando issuer y audience están ausentes, salvo que el operador habilite explícitamente jwtAllowMissingIssuerAndAudience. Este opt-out tiene false como valor predeterminado. El cambio convierte una política implícita y permisiva en una decisión visible de configuración.

  • Actualiza preferentemente a Apache Camel 4.22.0 o posterior
  • En la línea 4.14.x, usa al menos 4.14.9 y configura jwtIssuer, jwtAudience o ambos
  • En la línea 4.18.x, usa al menos 4.18.4 y configura jwtIssuer, jwtAudience o ambos
  • No trates la actualización a 4.14.9 o 4.18.4 como corrección automática, el valor predeterminado permisivo se mantuvo en esas líneas
  • Mantén jwtAllowMissingIssuerAndAudience deshabilitado en 4.22.0 o posterior
  • Restringe el keystore al menor conjunto posible de claves, idealmente con un signer dedicado al servicio
  • Garantiza que el backend y la interfaz de administración no puedan evitar la validación realizada por el gateway

Qué cambia esto en el alcance de un pentest

Probar JWT no termina al intentar alg none o modificar la firma. Un pentest de API necesita probar la frontera entre servicios: token correcto para el usuario, pero incorrecto para el recurso; clave confiable, pero emisor inesperado; acceso negado en el gateway, pero aceptado por el backend. La CVE-2026-66908 es un buen ejemplo de una falla que supera un checklist superficial y aparece cuando la prueba sigue la identidad completa, desde la emisión hasta cada punto que toma la decisión de acceso.

← Volver al blog

¿Quieres esa misma profundidad aplicada a tu entorno?

Cuéntanos qué necesitas validar y el equipo arma un alcance de pentest a medida.

Hablar por WhatsApp

¿Listo para evaluar el riesgo de su empresa?