JSON Web Tokeneid (JWT) kasutatakse laialdaselt API-de autentimiseks ja ühekordseks sisselogimiseks (SSO). Vorming on lihtne, kuid jätab palju turvaotsuseid arendaja ja teegi hooleks. RFC 8725 ehk JWT parimad praktikad (Best Current Practices) koondab teadaolevad vead ja nende vältimise viisid; see artikkel käsitleb neid, mida meie kontrolliksime esimesena.
JWT on allkirjastatud, mitte salajane
Standardis RFC 7519 määratletud allkirjastatud JWT-l on kolm punktidega eraldatud osa: päis, väidetest (claims) koosnev sisu ja allkiri. Esimesed kaks on ainult base64url-kodeeritud. Igaüks, kellel on tõend, saab neid lugeda. Siin on dekodeeritud näide:
{
"alg": "RS256",
"typ": "at+jwt",
"kid": "2026-10-key-1"
}
{
"iss": "https://auth.example.eu",
"sub": "user-4821",
"aud": "api.example.eu",
"iat": 1792140000,
"exp": 1792140900,
"role": "editor"
}
Allkiri tõendab, et väiteid ei ole muudetud. See ei peida neid. RFC 7519 ütleb, et kui tõend sisaldab privaatsustundlikku teavet, tuleb selle avalikustamise vältimiseks võtta meetmeid, näiteks kasutada krüpteeritud JWT-d (JWE). Praktikas hoidke sisust eemal isikuandmed, sisemised identifikaatorid, mida te ei avaldaks, ja kõik salajane.
1. lõks: väärtuse "alg": "none" aktsepteerimine
RFC 7519 lubab „turvamata“ JWT-sid, millel on "alg": "none" ja tühi allkiri. RFC 8725 kirjeldab teeke, mis aktsepteerisid selliseid tõendeid ja jätsid allkirja kontrolli täielikult vahele. Ründaja sai seejärel kirjutada mis tahes väiteid.
RFC 7518 sätestab, et implementatsioonid ei tohi vaikimisi turvamata tõendeid aktsepteerida, ja OWASP REST Security Cheat Sheet ütleb, et neid ei tohi üldse lubada. Kontrollige, et teie teek lükkab none tagasi, ja testige seda spetsiaalselt koostatud tõendiga.
2. lõks: tõendil lastakse algoritm valida
Päise väärtuse alg valib see, kes tõendi tegi, ja see võib olla ründaja. RFC 8725 kirjeldab klassikalist segiajamisrünnakut: server ootab RS256 allkirja, mida kontrollitakse RSA avaliku võtmega. Ründaja muudab väärtuse alg HS256-ks ja allkirjastab tõendi HMAC-iga, kasutades saladusena sedasama avalikku võtit. Päist järgiv teek kontrollib selle edukalt ja avalik võti on definitsiooni järgi avalik.
Lahendus on otsustada algoritm serveris. OWASP ütleb, et kontrollimisel ei tohi algoritmi valimiseks tugineda JWT päisele. RFC 8725 lisab, et iga võtit tuleks kasutada täpselt ühe algoritmiga. Koodis näeb see välja umbes nii:
verify(token,
key = issuer_public_key,
algorithms = ["RS256"],
issuer = "https://auth.example.eu",
audience = "api.example.eu")
3. lõks: nõrgad HMAC-saladused
HS256 puhul saab igaüks, kes tõendi kätte saab, proovida saladust võrguväliselt ära arvata nii kiiresti, kui tema riistvara võimaldab. RFC 8725 sätestab, et inimesele meeldejäävaid paroole ei tohi otse HMAC-võtmetena kasutada. RFC 7518 nõuab võtit, mis on vähemalt räsi väljundi pikkune, seega HS256 puhul 256 bitti.
openssl rand -base64 32
See annab 32 juhuslikku baiti ehk 256 bitti. Hoidke seda saladuste halduris, mitte koodihoidlas.
Jagatud saladustel on teinegi nõrkus. Iga teenus, mis saab HMAC-tõendit kontrollida, saab selle ka luua. Seetõttu eelistab OWASP MAC-idele allkirju: kui tõendeid valideerib mitu teenust, võiks üks kompromiteeritud teenus muidu luua tõendeid kõigi jaoks. Asümmeetrilised algoritmid, nagu RS256 või ES256, võimaldavad jagada ainult avalikku võtit.
4. lõks: väidete valideerimata jätmine
Kehtiv allkiri tõendab ainult seda, kes tõendi väljastas. Väited otsustavad, kas see teenus peaks selle praegu aktsepteerima.
exp: RFC 7519 järgi ei tohi tõendit aktsepteerida sel ajal või pärast seda. Lubatud on väike varu kellade erinevuse jaoks, tavaliselt mitte üle paari minuti.nbf: kui see on olemas, lükake tõend enne seda aega tagasi.iss: kontrollige, et väljastaja on see, keda usaldate, ja et allkirjastamisvõti kuulub talle.aud: RFC 7519 järgi tuleb tõend tagasi lükata, kui teenus ei leia ennast sihtrühmast.
OWASP soovitab API juurdepääsutõendite puhul vaikimisi nõuda ja valideerida väiteid iss, aud ja exp. RFC 8725 selgitab, miks sihtrühm on oluline. Ilma selleta saab ühele teenusele väljastatud tõendit uuesti kasutada mõnes teises teenuses, mis usaldab sama väljastajat. Samuti soovitab see selgesõnalist tüübistamist päisega typ, et üht liiki tõendit ei saaks kasutada seal, kus oodatakse teist. OAuthi juurdepääsutõendite puhul kasutab RFC 9068 väärtust at+jwt, nagu ülaltoodud näites.
5. lõks: kid, jku ja x5u usaldamine
Ka päiseparameetrid, mis ütlevad serverile, kust võti leida, on ründaja kontrolli all. RFC 8725 loetleb riskid:
- andmebaasi- või kataloogipäringus kasutatav
kid(võtme ID) võib võimaldada SQL- või LDAP-süstimist. Sama kehtib juhul, kui seda kasutatakse failitee koostamiseks. jkujax5uviitavad URL-ile, kust võtmeid laadida. Mis tahes URL-i järgimine võimaldab serveripoolset päringuvõltsimist (SSRF) ja ründaja võib suunata selle oma võtmele.
Käsitlege kid-i läbipaistmatu sildina ja otsige see fikseeritud loendist, mis koosneb teie kontrollitavatest võtmetest. Laadige võtmeid ainult lubatud URL-ide loendist; RFC 8725 lisab, et nende päringutega ei tohiks küpsiseid saata.
6. lõks: pikaealised tõendid ja tühistamise puudumine
JWT jääb kehtima kuni aegumiseni, isegi pärast seda, kui kasutaja logib välja või administraator konto keelab. OWASP märgib, et tõendid võivad elada kauem kui seanss, mida need esindavad.
- Hoidke juurdepääsutõendid lühiajalised: minutites, mitte päevades.
- Kasutage värskendustõendeid, mida server kontrollib iga kasutuse korral ja saab tühistada.
- Väljalogimiste ja kontode peatamise jaoks pidage OWASP-i soovitusel tõendi ID-de (
jti) keelunimekirja, kuni need tõendid aeguvad. - Vahetage allkirjastamisvõtmeid kindla ajakava järgi ja omage erakorralise vahetuse jaoks testitud protsessi.
7. lõks: tõendite salvestamine sinna, kus skriptid neid lugeda saavad
localStorage’is hoitud tõendeid saab lugeda iga lehel olev JavaScript. OWASP HTML5 Security Cheat Sheet hoiatab, et üksainus saitidevahelise skriptimise (XSS) viga võib varastada kõik nendes salvestusobjektides oleva, ja soovitab mitte hoida seal seansiidentifikaatoreid.
Brauserirakenduste puhul hoiab HttpOnly, Secure küpsis sobiva SameSite seadega tõendi skriptidest eemal. Küpsistega kaasneb saitidevahelise päringuvõltsimise (CSRF) risk, seega planeerige ka selle jaoks. Mida iganes valite, tugev sisuturbepoliitika (Content Security Policy) vähendab XSS-i tõenäosust juba eos.
Valideerimise kontrollnimekiri
- Fikseerige aktsepteeritavad algoritmid serveris ja lükake
nonetagasi. - Kasutage teeki, mis kontrollib allkirja enne, kui loete mis tahes väiteid.
- Valideerige
exp,nbf,issjaaudiga päringu puhul. - Kasutage tõenditüüpide eristamiseks
typ-i või eri sihtrühmi. - Otsige võtmeid
kidjärgi fikseeritud komplektist; ärge kunagi laadige võtmeid suvalistelt URL-idelt. - Kasutage vähemalt 256-bitiseid juhuslikke HMAC-võtmeid või asümmeetrilisi võtmeid.
- Hoidke sisu vaba saladustest ja ebavajalikest isikuandmetest.
- Hoidke juurdepääsutõendid lühiajalised ja toetage tühistamist.
- Hoidke brauseri tõendeid JavaScriptile kättesaamatus kohas.
Kust alustada
Kleepige oma testkeskkonna tõend meie JWT-dekoodrisse, et näha täpselt, mida see paljastab, ja kontrollige selle väärtusi alg, aud ja exp selle loendi alusel. Ärge kleepige tootmiskeskkonna kehtivaid tõendeid ühtegi veebitööriista.
Kui soovite teist arvamust oma autentimislahenduse kohta või tõendite käsitlemise koodiülevaatust, aitab meie turvalise tarkvaraarenduse meeskond.
