I JSON Web Token (JWT) sono ampiamente usati per l’autenticazione stateless nelle API REST. La loro struttura — header, payload e firma in Base64 separati da punti — espone però a vulnerabilità specifiche quando la libreria o la configurazione non è corretta. La voce JWT descrive la struttura e l’uso corretto; questa voce si concentra sulle classi di attacco.
Algoritmo none
Lo standard JWT prevede l’algoritmo speciale none per token non firmati. Alcune librerie lo accettano anche quando ricevono token da client non fidati:
# Header originale
{"alg": "RS256", "typ": "JWT"}
# Header modificato dall'attaccante
{"alg": "none", "typ": "JWT"}
L’attaccante codifica in Base64 un payload con "ruolo": "admin", imposta alg: none nell’header, e invia il token senza firma (o con firma vuota). Se la libreria accetta none senza restrizioni, il token viene validato come autentico.
Difesa: le librerie devono ricevere esplicitamente la lista degli algoritmi accettati e non devono mai includere none per token provenienti da client esterni.
Key Confusion RS256 → HS256
Questa vulnerabilità sfrutta la confusione tra crittografia asimmetrica e simmetrica:
- RS256: il server firma con la chiave privata RSA e verifica con la chiave pubblica RSA.
- HS256: il server firma e verifica con la stessa chiave segreta simmetrica.
La chiave pubblica RSA del server è — per definizione — pubblica e spesso ottenibile. L’attaccante:
- Ottiene la chiave pubblica RSA del server (da JWKS endpoint, certificato TLS, codice sorgente).
- Modifica il payload del token (es. eleva i propri privilegi).
- Ri-firma il token con HS256 usando la chiave pubblica RSA come segreto simmetrico.
- Imposta
alg: HS256nell’header.
Se il server usa la chiave pubblica RSA anche come chiave HMAC per verificare i token HS256 (alcune implementazioni vulnerabili lo fanno), il token forgiato viene accettato.
Difesa: la libreria deve verificare il token usando l’algoritmo configurato server-side, ignorando l’algoritmo dichiarato nell’header del token. Il campo alg dell’header non è trusted.
Manipolazione del payload non firmato
Il payload JWT è codificato in Base64url ma non cifrato. Chiunque intercetti il token può leggere le claim. Se dati sensibili (email, ruolo, permessi) sono nel payload e il token transita su canali non cifrati (assenza di TLS), i dati sono esposti.
Questo non è una vulnerabilità del JWT in sé, ma un errore di architettura: il JWT garantisce integrità (non falsificabilità), non confidenzialità.
Attacco al JWKS endpoint
Alcune implementazioni accettano un parametro jku (JWK Set URL) o x5u nell’header del token, che indica dove recuperare le chiavi pubbliche per la verifica. Un attaccante può:
- Creare una propria coppia di chiavi RSA.
- Inserire nell’header
jku: https://evil.it/mie-chiavi.json. - Firmare il token con la propria chiave privata.
Se il server scarica le chiavi dal jku senza verificare che il dominio sia nella lista bianca, verifica il token con la chiave dell’attaccante — che corrisponde — e lo accetta.
Difesa: ignorare jku, x5u e kid se puntano a URL esterne; usare solo chiavi configurate staticamente server-side.
JWT con kid injection
Il parametro kid (Key ID) nell’header indica quale chiave usare per la verifica. Alcune implementazioni costruiscono una query SQL o un path di file usando il valore di kid senza sanitizzazione:
# Vulnerabile
key = db.query(f"SELECT chiave FROM jwt_keys WHERE id = '{kid}'")
Un attaccante può iniettare:
{"kid": "' UNION SELECT 'chiave_attaccante' --", "alg": "HS256"}
Facendo restituire dal database la stringa chiave_attaccante come chiave di verifica — che l’attaccante conosce e può usare per firmare token arbitrari.
Il kid può anche essere usato per un attacco di path traversal se viene usato come nome di file.
Scadenza e revoca
I JWT sono stateless: una volta emessi, sono validi fino alla scadenza (exp). Se le credenziali di un utente vengono compromesse, non esiste un meccanismo nativo per invalidare i token esistenti prima della scadenza. Le soluzioni comuni — lista di revoca (denylist) o token di breve durata con refresh token — introducono stato e aumentano la complessità.
Relazione con altri argomenti
- JWT — struttura, uso corretto e flusso di emissione.
- Crittografia Asimmetrica — base dell’algoritmo RS256.
- HMAC — base dell’algoritmo HS256.
- Protocollo TLS — necessario per proteggere il token in transito.
- OWASP Top 10 — A07 Identification and Authentication Failures.