## https://sploitus.com/exploit?id=KITPLOIT:TOOLS-GITHUB-OSCERD-CVE-2026-23552
# CVE-2026-23552 - Aceptación de tokens entre reinos en camel-keycloak
## Resumen
La `KeycloakSecurityPolicy` de Apache Camel no valida la reclamación `iss` (emisor) de los tokens JWT contra el reino configurado. Esto significa que un token emitido por un reino de Keycloak es aceptado silenciosamente por una polÃtica configurada para un reino completamente diferente, rompiendo el aislamiento entre inquilinos.
Versiones afectadas: 4.15.0, 4.16.0, 4.17.0
Seguimiento en: https://issues.apache.org/jira/browse/CAMEL-22854
## Causa raÃz
En `KeycloakSecurityHelper.parseAccessToken()`, cuando no se proporciona explÃcitamente una clave pública (que es la configuración predeterminada), el token solo se decodifica desde Base64 -- nunca se verifica:
root@kitploit:~
public static AccessToken parseAccessToken(String tokenString, PublicKey publicKey)
throws VerificationException {
if (publicKey != null) {
return TokenVerifier.create(tokenString, AccessToken.class)
.publicKey(publicKey)
.verify()
.getToken();
} else {
// no signature verification, no issuer check
return TokenVerifier.create(tokenString, AccessToken.class).getToken();
}
}
Dado que la ruta de código predeterminada llega a la rama `else`, tres cosas quedan sin comprobar:
1. La firma del token nunca se verifica
2. La reclamación `iss` nunca se compara con el esperado `{serverUrl}/realms/{realm}`
3. No se obtiene ninguna clave pública JWKS de Keycloak
La comprobación de roles sigue pasando porque solo examina los nombres de los roles dentro del payload del token. Si el nombre del rol (`tenant-user`) coincide entre reinos -- lo cual es común en configuraciones multiinquilino -- la solicitud pasa.
## Impacto
En una aplicación multiinquilino donde cada inquilino se asigna a un reino de Keycloak separado, un usuario del inquilino A puede acceder a rutas protegidas para el inquilino B. Concretamente:
* Acceso a datos entre inquilinos en aplicaciones SaaS multiinquilino
* Escalada de privilegios cuando diferentes reinos tienen diferentes configuraciones de roles
* Bypass completo del aislamiento de seguridad basado en reinos
## Reproducción
Este proyecto demuestra la vulnerabilidad usando Apache Camel 4.17.0 y una instancia local de Keycloak.
### Requisitos previos
* Java 17+
* Maven 3.9+
* CLI de Camel JBang (`jbang app install camel@apache/camel`)
* Docker o Podman (usados por `camel infra` internamente)
### Configuración
Inicie un Keycloak local:
root@kitploit:~
camel infra run keycloak
Esto inicia Keycloak en `localhost:8080` con las credenciales de administrador `admin`/`admin`.
### Ejecución
root@kitploit:~
mvn verify
### Qué sucede
La prueba de integración (`CrossRealmTokenBypassIT`) hace lo siguiente:
1. Se conecta al Keycloak local y crea dos reinos: `acme` y `globex`
2. Crea un cliente confidencial en cada reino con concesión de acceso directo habilitada
3. Crea el rol de reino `tenant-user` en ambos reinos
4. Crea a la usuaria `alice` (contraseña `alice123`) en el reino `acme` y le asigna el rol `tenant-user`
5. Configura una ruta Camel (`direct:globex-protected`) protegida por una `KeycloakSecurityPolicy` vinculada al reino `globex`
6. Obtiene un token JWT para `alice` del reino `acme` (emisor: `http://localhost:8080/realms/acme`)
La solicitud tiene éxito. El token de `acme` pasa la polÃtica de `globex` sin ningún error.
### Resultados esperados de las pruebas en 4.17.0
Test| Resultado| Significado
---|---|---
En una versión parcheada (4.18.0+), la segunda prueba fallarÃa y la tercera pasarÃa.
### Limpieza
root@kitploit:~
camel infra stop keycloak
La prueba también elimina los reinos `acme` y `globex` en `@AfterAll`.
## Corrección
La `KeycloakSecurityPolicy` deberÃa rechazar los tokens donde la reclamación `iss` no coincida con `{serverUrl}/realms/{realm}`. La corrección está registrada en CAMEL-22854 y se incluirá con Camel 4.18.0 (la próxima versión LTS).