JWT Hyökkäykset

JWT Tokenit

Helppo
20 min

Mikä ihmeen JWT?

JWT on lyhennys sanoista JSON Web Token, jolla viitataan nykyään hyvin yleiseen tapaan kuljettaa pieniä määriä tietoja selaimen ja palvelimen, tai tietojärjestelmien välillä, digitaalisesti allekirjoitetussa muodossa.

JWT-tokenit näyttävät yleensä tältä: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Jos katsoo tarkkaan, huomaa että tokenissa on kolme osaa, jotka on eroteltu pisteillä.

  • Ensimmäinen osa: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
  • Toinen osa: eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
  • Kolmas osa: SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Kaikki tokenin osat ovat base64-enkoodattuja. Base64 on varsin yleisesti käytössä oleva tapa muuttaa minkälaista dataa tahansa muotoon, joka koostuu 64 eri merkistä, ja takaisin.

1. Osa: JOSE-Otsake

Tokenin ensimmäinen osa on JOSE (Javascript Object Signing and Encryption) otsake ("header"), joka sisältää tietoa esimerkiksi tokenin salaus- tai allekirjoitusalgoritmista.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 on (base64) dekoodattuna:

{"alg":"HS256","typ":"JWT"}

alg: Salaus/allekirjoitusalgoritmi. HS256 tarkoittaa algoritmia "HMAC with SHA-256", joka on symmetrinen allekirjoitusalgoritmi, tarkoittaen että digitaalinen allekirjoitus tehdään ja allekirjoitetaan samalla salausavaimella.

typ: Ei käytetä juuri mihinkään, arvo on yleensä JWT.

2. Osa: Data

Toinen osa sisältää tokenin tiedot (puhutaan myös tokenin datasta, tai payloadista). eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ on base64-dekoodattuna:

{"sub":"1234567890","name":"John Doe","iat":1516239022}

Data-osion tiedot ovat myös nimeltään "claimeja". Tyypillisesti tokenissa on jonkinlainen käyttäjätunniste, mahdollisesti listaus käyttäjän oikeuksista, ja yleensä myös tieto siitä että milloin token on luotu, ja milloin se lakkaa olemasta voimassa.

Esimerkkitokenissa on seuraavat claimit:

  • sub: Subjekti, tässä tapauksessa käyttäjän tunnus.
  • name: Käyttäjän nimi
  • iat: "Issued at", eli epoch-muotoinen aikaleima joka kertoo että milloin token on myönnetty.

Usein näkee myös seuraavia claimeja:

  • iss: "Issuer", kuka tokenin on myöntänyt.
  • aud: "Audience", kenelle token on tarkoitettu käsiteltäväksi.
  • exp: "Expiration time", epoch-muotoinen aikaleima joka kertoo että milloin token lakkaa olemasta voimassa.
  • nbf: "Not before", milloin token astuu voimaan.
  • jti: "JWT ID", uniikki tunniste juuri tälle tokenille. Voidaan käyttää esimerkiksi estämään ettei samaa tokenia käytetä uudestaan, tai revokoimaan (poistamaan käytöstä) myönnetty token.

3. Osa: Allekirjoitus

JWT-tokenin kolmas osa on digitaalinen allekirjoitus. SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c on base64-dekoodattuna I�J�IHNJ(]�O���lj~�:N�%_�u ,×. Siis siansaksaa.

Koska algoritmi on HS256, eli HMAC + SHA256, digitaalinen allekirjoitus on, hieman yksinkertaistaen, muodostettu seuraavasti:

  • A: Otetaan 1. Osa eli JOSE-otsake ja base64-enkoodataan se.
  • B: Otetaan 2. Osa eli tokenin tietosisältö, ja base64-enkoodataan sekin.
  • C: Yhdistetään pisteellä A ja B. Lopputulos, eli allekirjoitettava viesti on jotain tämännäköistä: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
  • Otetaan salausavain K ja yhdistetään siihen allekirjoitettava viesti C.
  • Ajetaan yhdistelmä (K + C) tiivistealgoritmin (tässä tapauksessa SHA256) läpi, ja saadaan valmis digitaalinen allekirjoitus.

Allekirjoituksen tarkastus

Kun JWT-toteutus tarkastaa onko tokenin allekirjoitus kunnossa, sen täytyy:

  • Tietää että millä algoritmilla token on allekirjoitettu.
  • Käyttää algoritmia ja laskea JWT:stä allekirjoitus.
  • Verrata laskemaansa allekirjoitusta tokenin mukana tulleeseen allekirjoitukseen, ja varmistaa että ne täsmäävät.
  • Tarkistaa että onko token vanhentunut, tai eikö se mahdollisesti ole vielä voimassa.
  • Jne.

JWT-haavoittuvuudet

JWT on monipuolinen protokolla ja sitä on historiallisesti väärinymmärretty sekä toteutuksissa (kuten JWT-ohjelmistokirjastot joita sovellukset käyttävät) että niiden käytössä (sovellukset jossa JWT-käsittelijää ei ole määritetty turvallisesti).

Mistä JWT-tarkastuksen esimerkiksi pitäisi päätellä, että mitä algoritmia käytetään, jos kehittäjä ei ole sitä erikseen sovelluksen koodissa kertonut? Aivan passeli ja luonteva vastaus on että "JOSE-otsakkeesta". Sen takiahan se siellä lukee. Mutta mitäs jos hyökkääjä muunteleekin tokenin tietoja haluamansa laiseksi (vaikka "userId": "admin"), ja laittaa sitten tokenin algoritmiksi "none", eli allekirjoitusta ei tarvita? Jos sovellus hyväksyy tällaisen tokenin, seuraukset on katastrofaaliset.

Entä mitä jos JWT:n allekirjoituksessa on käytetty liian heikkoa salaisuutta, ja hyökkääjä onnistuu arvaamaan sen, ja sitten luomaan omia tokeneita?

Näihin, ja muihinkin JWT:ihin liittyviin tietoturvatöpläyksiin tutustumme tällä kurssilla!

hakatemia pro

Valmis ryhtymään eettiseksi hakkeriksi?
Aloita jo tänään.

Hakatemian jäsenenä saat rajoittamattoman pääsyn Hakatemian moduuleihin, harjoituksiin ja työkaluihin, sekä pääset discord-kanavalle jossa voit pyytää apua sekä ohjaajilta että muilta Hakatemian jäseniltä.