Un JSON Web Token viene spesso usato per trasportare informazioni tra sistemi. Il suo formato compatto può sembrare cifrato o intrinsecamente affidabile, ma non lo è.
Tre parti, generalmente leggibili
Un JWT classico contiene header, payload e firma separati da punti. Le prime due parti sono codificate, non necessariamente cifrate. Non inserire quindi segreti nel payload pensando che siano invisibili.
Un decoder o inspector permette di leggere localmente i campi del token, ma questa operazione descrive soltanto il contenuto.
Decodificare non significa verificare
Mostrare il payload prova soltanto che la stringa può essere interpretata secondo il formato. Per fidarsi dei claim, l’applicazione deve verificare la firma con la chiave e l’algoritmo attesi e poi applicare i propri controlli.
Cosa prova la firma
La firma viene calcolata a partire dalle parti codificate del token e da una chiave secondo l’algoritmo scelto. Se verificata correttamente, permette di rilevare modifiche e di stabilire che il token è stato firmato da un’entità che possiede la chiave attesa. Non rende il payload confidenziale.
Algoritmi simmetrici come HS256 utilizzano un segreto condiviso; famiglie asimmetriche come RS256 o ES256 separano la chiave privata di firma dalla chiave pubblica di verifica.
L’applicazione deve imporre gli algoritmi accettati e non fidarsi ciecamente del valore dichiarato nel token.
Scadenza, audience ed emittente
Claim come exp, nbf, iat, iss e aud sono utili soltanto se vengono davvero verificati. Accettare un token scaduto, destinato a un’altra audience o emesso da un soggetto inatteso può annullare una parte fondamentale della protezione.
Una piccola tolleranza per differenze di orologio tra sistemi può essere ragionevole, ma non deve trasformarsi in un prolungamento eccessivo della validità.