
CVE-2026-29000 - pac4j-jwt (< 4.5.9 / < 5.7.9 / < 6.3.3) PoC di bypass dell'autenticazione in JwtAuthenticator
JwtAuthenticator di pac4j-jwt — PoCUna proof-of-concept per CVE-2026-29000, un bypass dell'autenticazione nel componente
pac4j-jwt JwtAuthenticator
(CVSS 10.0, Critica).
Lo script forgia un token che impersona qualsiasi utente con qualsiasi ruolo — senza conoscere alcun segreto — purché il target esponga la sua chiave pubblica RSA.
[!WARNING] Questo strumento è fornito solo per scopi educativi e test di sicurezza autorizzati. È stato scritto per risolvere la macchina Hack The Box "Principal", e i valori predefiniti (
iss,role,kid) sono calibrati su quella macchina. Usalo solo contro sistemi di tua proprietà o per i quali sei esplicitamente autorizzato a fare test.
Le versioni di pac4j-jwt < 4.5.9, < 5.7.9 e < 6.3.3 contengono un difetto
logico in JwtAuthenticator quando elabora JWT cifrati (JWE).
Quando JwtAuthenticator decifra una JWE, tenta di analizzare il token interno come un
SignedJWT. Se il token interno è un PlainJWT non firmato (alg: none), l'oggetto
SignedJWT restituisce null e, a causa dell'errore logico, il
percorso di verifica della firma viene saltato del tutto. L'autenticatore quindi
costruisce un profilo utente direttamente dalle attestazioni non verificate.
In altre parole, la cifratura esterna JWE — che richiede solo la chiave pubblica del server — viene scambiata per prova di autenticità, quindi qualsiasi attaccante che possa leggere la chiave pubblica può coniare token completamente attendibili.
/api/auth/jwks).PlainJWT non firmato (alg: none) con attestazioni scelte
dall'attaccante (sub, role, iss, …).PlainJWT in un involucro JWE cifrato con la chiave pubblica del target.Bearer. Il JwtAuthenticator
vulnerabile la decifra, salta la verifica della firma e si fida delle
attestazioni forgiate.requirements.txt:pip install -r requirements.txt
(requests, jwcrypto, cryptography)
python3 exploit.py -u <username> [options]
| Flag | Descrizione | Predefinito |
|---|---|---|
-t, --target | URL di base del target (es. http://host:8080) | — |
--jwks-url | Percorso dell'endpoint JWKS | /api/auth/jwks |
--jwks-file | Carica JWKS da un file locale invece di recuperarlo da --target | — |
-u, --username | Valore per l'attestazione sub (obbligatorio) | — |
--role | Valore per l'attestazione role | ROLE_ADMIN |
--iss | Valore per l'attestazione iss | principal-platform |
--exp | Validità del token in secondi | 3600 |
--verify-endpoint | Endpoint protetto su cui testare il token forgiato (es. /api/settings) | — |
-k, --insecure | Disabilita la verifica del certificato TLS | off |
-o, --output | Scrive la JWE forgiata su un file invece che su stdout | stdout |
-v, --verbose | Stampa il payload JWT forgiato su stderr | off |
Devi fornire --target (per recuperare il JWKS dalla rete) oppure
--jwks-file (per fornirlo localmente).
Forgia un token admin recuperando la chiave pubblica dal target e stampalo su stdout:
python3 exploit.py -t http://target:8080 -u admin
Forgia un token, poi testalo automaticamente contro un endpoint protetto:
python3 exploit.py -t http://target:8080 -u admin \
--verify-endpoint /api/settings -v
Usa un JWKS salvato localmente e salva il token su un file:
python3 exploit.py --jwks-file jwks.json -u admin -o token.jwe
Aggiorna org.pac4j:pac4j-jwt a una release corretta:
Rilasciato sotto la Licenza MIT.