
CVE-2026-29000 - pac4j-jwt (< 4.5.9 / < 5.7.9 / < 6.3.3) PoC de bypass de autenticación de JwtAuthenticator
JwtAuthenticator de pac4j-jwt — PoCUna prueba de concepto para CVE-2026-29000, un bypass de autenticación en el
componente pac4j-jwt JwtAuthenticator
(CVSS 10.0, Crítico).
El script forja un token que suplanta a cualquier usuario con cualquier rol — sin conocer ni un solo secreto — siempre y cuando el objetivo exponga su clave RSA pública.
[!WARNING] Esta herramienta se proporciona solo con fines educativos y para pruebas de seguridad autorizadas. Fue escrita para resolver la máquina de Hack The Box "Principal", y los valores predeterminados (
iss,role,kid) están adaptados a esa máquina. Úsala únicamente contra sistemas que poseas o para los que tengas autorización explícita de pruebas.
Las versiones de pac4j-jwt < 4.5.9, < 5.7.9 y < 6.3.3 contienen un
fallo de lógica en JwtAuthenticator cuando procesa JWTs cifrados (JWE).
Cuando JwtAuthenticator descifra un JWE, intenta analizar el token interno como
un SignedJWT. Si el token interno es un PlainJWT sin firmar (alg: none),
el objeto SignedJWT se devuelve como null y, debido al error de lógica, la
ruta de verificación de firma se omite por completo. El autenticador entonces
construye un perfil de usuario directamente a partir de las reclamaciones no verificadas.
En otras palabras, el cifrado JWE externo — que solo requiere la clave pública del servidor — se confunde con una prueba de autenticidad, por lo que cualquier atacante que pueda leer la clave pública puede acuñar tokens totalmente confiables.
/api/auth/jwks).PlainJWT sin firmar (alg: none) con reclamaciones elegidas por el atacante
(sub, role, iss, …).PlainJWT en un sobre JWE cifrado con la clave pública del objetivo.Bearer. El vulnerable
JwtAuthenticator lo descifra, omite la verificación de firma y confía en las
reclamaciones forjadas.requirements.txt:pip install -r requirements.txt
(requests, jwcrypto, cryptography)
python3 exploit.py -u <username> [options]
Debes proporcionar ya sea --target (para obtener el JWKS a través de la red) o
--jwks-file (para suministrarlo localmente).
Forjar un token de administrador obteniendo la clave pública del objetivo e imprimirlo en stdout:
python3 exploit.py -t http://target:8080 -u admin
Forjar un token y luego probarlo automáticamente contra un endpoint protegido:
python3 exploit.py -t http://target:8080 -u admin \
--verify-endpoint /api/settings -v
Usar un JWKS guardado localmente y guardar el token en un archivo:
python3 exploit.py --jwks-file jwks.json -u admin -o token.jwe
Actualiza org.pac4j:pac4j-jwt a una versión parcheada:
Publicado bajo la Licencia MIT.
| Flag | Descripción | Valor predeterminado |
|---|
-t, --target | URL base del objetivo (p. ej. http://host:8080) | — |
--jwks-url | Ruta del endpoint JWKS | /api/auth/jwks |
--jwks-file | Cargar JWKS desde un archivo local en lugar de obtenerlo desde --target | — |
-u, --username | Valor para la reclamación sub (obligatorio) | — |
--role | Valor para la reclamación role | ROLE_ADMIN |
--iss | Valor para la reclamación iss | principal-platform |
--exp | Validez del token en segundos | 3600 |
--verify-endpoint | Endpoint protegido para probar el token forjado (p. ej. /api/settings) | — |
-k, --insecure | Deshabilitar la verificación del certificado TLS | off |
-o, --output | Escribir el JWE forjado en un archivo en lugar de stdout | stdout |
-v, --verbose | Imprimir el payload JWT forjado en stderr | off |