Vai al contenuto
Token security

Audit di sicurezza per token JWT

Incolla un token JWT e ottieni un audit security-first: rilevamento di alg=none, brute-force di un secret HS256 contro un dizionario di 50 secret comuni, claim mancanti (exp, iat, aud, iss, jti), lifetime sospetto oltre i 30 giorni, header kid con caratteri da injection, jku e x5u non pinnati. Per la sola lettura del token (claim explainer, expiry countdown, verifica HS256 opzionale) c'è il JWT decoder; questo audit assume la firma valida e si concentra sulla postura di sicurezza della configurazione.

Come usare l'audit

  1. 1

    Recupera un JWT

    Tipico flow: cattura il token dalla request HTTP del browser (DevTools > Network > header Authorization: Bearer...), oppure da log applicativi, oppure da copia diretta dell'output del tuo identity provider in fase di test.

  2. 2

    Incolla il token

    Tre parti separate da punto: header.payload.signature. Il tool valida il formato base64url e fallisce con messaggio chiaro se uno dei tre segmenti è malformato.

  3. 3

    Leggi i findings

    Output: header e payload decoded (visibili full-text per ispezione manuale) + lista findings security ordinati per severita' + punteggio indicativo 0-100. Ogni finding ha riferimento normativo e remediation suggerita.

  4. 4

    Stampa o copia il report

    Per integrare il report in un audit document o ticket interno: bottone 'Copia report' produce versione testuale; 'Stampa' del browser per export PDF (CSS print-ottimizzato che nasconde nav e CTA).

Vettori di attacco e claim mancanti

Il rischio reale dei JWT viene dalla configurazione, non dal formato. Leggere il payload di un token (cosa fa il JWT decoder) è la parte facile; chiedersi se quel token è esposto a uno dei pattern noti di compromissione è ciò che separa un'integrazione production-grade da un incidente in attesa di accadere.

Vettori di attacco classici verificati dall'audit. (1) alg=none: librerie JWT storicamente vulnerabili (jsonwebtoken < 8.5, jose < 4 fra le più note) accettavano header {"alg":"none"} bypassando la verifica della firma. Se il backend non rifiuta esplicitamente questo valore, un attaccante può forgiarsi token con qualunque payload. (2) HS256 con weak secret: HMAC con secret condiviso brute-forzabile offline se il secret è un dictionary word; l'audit prova un dizionario di 50 secret comuni e segnala HIGH se uno verifica la firma. (3) kid injection: l'header kid è usato dal backend come key path; se non sanitizzato si presta a path traversal (es. ../../../dev/null punta a file vuoto, secret = stringa vuota, forgery riuscita) o SQL injection nella tabella keys. (4) jku/x5u trust: header che dichiarano l'URL della chiave pubblica con cui verificarsi; senza pinning lato backend, un attaccante che controlla la URL controlla la chiave.

Claim mancanti. RFC 7519 definisce claim opzionali con valore di sicurezza: exp (expiration), nbf (not before), iat (issued at), jti (anti-replay), aud (audience, contro confused deputy), iss (issuer, contro rogue IdP). Anti-pattern frequente: token senza exp, che vivono per sempre senza possibilità di revoca server-side né rotazione automatica; oppure senza aud, che un service A può inoltrare a un service B che lo accetta perché coperto dallo stesso IdP.

Limite operativo. L'audit non verifica la firma del token: per quello serve la chiave del backend (HS256 secret o RS256 public key). Per la verifica HS256 opzionale c'è il campo dedicato del JWT decoder; per RS256/ES256 la verifica richiede il fetch del JWKS dell'IdP, ambito tipico dell'SDK ufficiale del provider in modalità debug. L'audit assume la firma valida e si concentra sui rischi di configurazione.

Regole di audit applicate

CheckSeverita'Riferimento
alg=none / alg=NoneCriticoCVE multipli (Auth0 lib 2015, jsonwebtoken < 8.5)
HS256 con secret nel dizionario di 50 secret comuniAltoOWASP JWT Cheatsheet
exp mancanteAltoRFC 7519 par. 4.1.4
exp già scaduto (info)InfoRFC 7519
iat mancanteBassoRFC 7519 par. 4.1.6
aud mancanteMedioOWASP confused deputy
iss mancanteMedioOWASP rogue IdP
jti mancanteBassoRFC 7519 par. 4.1.7 (anti-replay)
Lifetime > 30 giorni (exp - iat)AltoOWASP JWT Cheatsheet
kid presente con caratteri sospetti (path traversal, SQLi)MedioOWASP injection
jku presenteAltoOWASP JWT spec abuse
x5u presenteAltoOWASP JWT spec abuse
typ mancanteInfoRFC 7519 par. 5.1

Glossario

Termini tecnici usati in questa pagina, spiegati in due righe.

JWT #
JSON Web Token, RFC 7519. Stringa formato header.payload.signature, base64url-encoded ognuno. Contiene claim JSON sull'identità o sull'autorizzazione. Standard de facto per API authentication moderne.
alg=none #
Valore dell'header alg che indica firma assente. RFC 7518 par. 3.6 lo definisce come opzione, ma OWASP raccomanda di rifiutarlo a livello applicativo per evitare bypass di firma.
HS256 #
HMAC-SHA256, signature simmetrica con secret condiviso fra issuer e verifier. Il secret deve essere casuale (>= 256 bit di entropia, non una passphrase umana) per resistere a brute force offline.
RS256 #
RSA-SHA256, signature asimmetrica. Il backend ha la chiave privata per firmare, i client (o altri service) hanno solo la pubblica per verificare. Preferito a HS256 per architetture multi-service.
ES256 #
ECDSA-SHA256 con curva P-256. Equivalente a RS256 ma con chiavi più corte (256 bit vs 2048-4096) e firme più veloci. Raccomandato per nuovi sistemi.
kid #
Key ID, header opzionale che identifica quale chiave usare per verifica (utile in JWKS multi-key). Vulnerabilita' note se non sanitizzato lato backend (path traversal, SQLi).
JWKS #
JSON Web Key Set. Endpoint pubblico che pubblica le chiavi pubbliche di un IdP. URL convenzione: https://idp/.well-known/jwks.json.
exp / iat / nbf #
Claim temporali (RFC 7519). exp: expiration timestamp Unix. iat: issued at. nbf: not before. Tutti in secondi (non millisecondi).

Domande frequenti sull'audit JWT

Il tool decodifica anche la firma? Posso vederla?
Il terzo segmento (signature) viene mostrato come stringa base64url, non decodato. Le firme HMAC, RSA ed ECDSA sono byte raw e leggerle non aggiunge informazioni utili. Per verificarla serve la chiave: per HS256 usa il JWT decoder con secret nel campo dedicato (calcolo locale in WebCrypto), per RS256/ES256 l'SDK del tuo identity provider in modalità debug.
Cosa succede se HS256 viene rilevato con un secret debole?
Il tool prova 50 secret comuni in JS lato browser ("secret", "password", "key", "my-secret-key", "changeme", ecc). Se uno verifica la firma, alza un finding HIGH dicendo "il secret HS256 è uno dei 50 più comuni\". Il pattern di mitigation: ruotare immediatamente il secret a una stringa random crypto-safe da 32+ byte. Per generarlo: openssl rand -base64 32.
Token scaduto: è un finding bloccante?
No, è classificato INFO. Un token scaduto NON è una vulnerabilita' di sicurezza (anzi, l'expiration è una mitigazione). Il tool segnala lo stato per evitare false positive nel report (un audit che dice "manca exp\" su token che invece ha exp ma è scaduto sarebbe un bug).
Lifetime > 30 giorni è realmente un problema?
Dipende dal use case. Per token di sessione utente: si', 30 giorni è troppo, refresh token rotation con access token short-lived (15-60 min) è la pratica raccomandata. Per token di servizio (API key formato JWT): 30+ giorni può essere accettabile se ruotati e revocabili lato backend. Il tool segnala HIGH come default conservativo: valuta il context e ignora se il use case lo giustifica.
kid injection: come si exploita davvero?
Esempi reali. (1) kid: "../../../dev/null" -> backend cerca chiave nel filesystem -> trova file vuoto -> verifica HMAC con secret = stringa vuota. Forgery. (2) kid: "key1' UNION SELECT 'attacker'-- " -> backend fa SQL su tabella keys -> SQLi -> chiave attacker controllata. Mitigation: trattare kid come input untrusted, whitelist alfanumerica + lookup esatto in mappa interna.
Perché jku/x5u sono dichiarati ad alto rischio?
Permettono al token di dichiarare la URL della chiave pubblica con cui verificarsi. Se il backend la usa as-is (senza pinning a domini fidati), un attaccante che controlla la URL controlla la chiave -> firme valide a piacere. Mitigation: pinning whitelist di hostname autorizzati a livello backend, oppure ignorare jku/x5u e usare solo JWKS endpoint hardcoded.
Il tool decode token JWE (encrypted)?
No. Il JWE (RFC 7516) ha 5 segmenti invece di 3 (header.encrypted_key.iv.ciphertext.tag) e il payload è cifrato, non leggibile senza chiave. JWT (RFC 7519) è typically signed-only (JWS), il payload è base64url plain. Il tool gestisce JWS classico.
Posso fare audit di un Refresh Token?
Si, sintatticamente i refresh token sono spesso JWT. Audit punti rilevanti: (a) exp deve essere lungo (giorni-mesi tipico), (b) jti presente per anti-replay (refresh token andrebbero invalidati al primo uso), (c) aud ristretto ad endpoint di refresh, (d) idealmente HS256 sostituito da RS256 in arch multi-service.
Posso fare un audit completo del flusso, non del singolo token?
Questo audit segnala i rischi visibili dal singolo token. Per esaminare il flusso completo (rotazione delle chiavi, refresh token rotation, logout server-side, anti-replay con jti, audience binding, gestione di kid e jku/x5u in produzione, configurazione del provider OIDC) serve una review architetturale che attraversi codice, configurazione del provider e infrastruttura: vai al CTA in fondo alla pagina.

La tua architettura JWT regge un audit serio?

Questo tool segnala i rischi visibili dal singolo token. Una review professionale esamina il flusso completo: configurazione del provider, rotazione chiavi, refresh token, logout server-side, anti-replay (jti), audience binding, gestione del kid e jku/x5u. Lavoro su backend PHP, Laravel, Symfony, Node, Python.

Review architettura JWT

Vuoi una stima realistica per il tuo progetto?

Wizard di 7 domande, 2 minuti, gratuito. Output: range di giorni-uomo, range di prezzo orientativo e raccomandazione di ingaggio. Tariffa di riferimento 300 euro al giorno. Pensato per progetti backend custom, integrazioni, audit di sicurezza o automazione AI.

Calcola il preventivo