
CVE-2026-29000 PoC: pac4j-jwt PlainJWT-in-JWE-Authentifizierungsumgehung.
Proof-of-Concept für CVE-2026-29000. Ziel sind pac4j-jwt-Versionen vor 4.5.9, 5.7.9 und 6.3.3.
Die Schwachstelle ist einfach: Die Bibliothek akzeptiert einen PlainJWT (unsigniert, alg=none), solange er in ein gültiges JWE eingebettet ist. Da der Server seinen RSA-öffentlichen Schlüssel über einen JWKS-Endpunkt bereitstellt, kann jeder einen beliebigen unsignierten JWT in ein JWE verschlüsseln, dem der Server vertraut – einschließlich eines mit ROLE_ADMIN.
alg=none) mit beliebigen Claims erstellenDer Server entschlüsselt es, vertraut den Claims darin und prüft nie, ob der innere JWT unsigniert ist.
Python 3.13+ mit uv oder Abhängigkeiten manuell installieren:
pip install jwcrypto requests
[uv run / python3] CVE-2026-29000.py --url <base_url> --jwks <jwks_path> [optionen]
Erforderlich:
| flag | beschreibung |
|---|---|
--url | Basis-URL des Ziels, z. B. http://10.10.11.x:8080 |
--jwks | Pfad oder vollständige URL zum JWKS-Endpunkt |
Optional:
Beispiele:
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
Nicht immer offensichtlich. Gute Orte zum Suchen:
/robots.txt – listet oft eingeschränkte oder interne Pfade auf/api/auth/jwks/.well-known/jwks.json/.well-known/openid-configurationWenn das Token abgelehnt wird, erwartet die App möglicherweise einen bestimmten Verschlüsselungsalgorithmus. Prüfe /static/js/app.js auf etwas wie:
const JWE_ALG = "RSA-OAEP-256";
const JWE_ENC = "A128GCM";
Dann erneut mit --enc A128GCM ausführen.
Die Token-Speichermethode ist dort normalerweise auch enthalten:
class TokenManager {
static getToken() {
return sessionStorage.getItem('auth_token');
}
}
Wenn es sessionStorage ist, tausche das Token direkt in den DevTools unter Anwendung > Sitzungsspeicher aus.
Behoben in 4.5.9, 5.7.9 und 6.3.3.
| flag | standard | beschreibung |
|---|
--user | admin | Wert für den sub-Claim |
--role | ROLE_ADMIN | Zu fälschende Rolle (ROLE_ADMIN, ROLE_MANAGER, ROLE_USER) |
--issuer | principal-platform | Wert für den iss-Claim |
--enc | A256GCM | JWE-Inhaltsverschlüsselung (A256GCM oder A128GCM) |