Czym jest JWT (JSON Web Token)?

JWT jest otwartym standardem (RFC 7519) definiującym sposób danych za pomocą obiektu JSON. Używany jest on przede wszystkim to autoryzacji oraz uwierzytelniania. Tokeny w przeważającej części są tworzone za pomocą sekretu bądź klucza prywatnego/publicznego. Piszę “przeważającej”, ponieważ może zdarzyć się, że JWT nie posiada sygnatury. Mówimy wtedy o “unsecured JWT”.

Ok, ale czym jest wspomniana sygnatura? Zacznijmy od tego, że nasz JSON Web Token składa się z trzech części. Należy do nich:

  • header
  • payload
  • signature

Każda z części oddzielona jest od siebie kropką, a przykładowy token może wyglądać w poniższy sposób.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkJ1Z3NwYWNlIiwiaWF0IjoxNTE2MjM5MDIyfQ.04eZFycQi8uO0HAhAiejW6id0MBbM34PTNXsb6WQr6Y

Po zmianie z zapisu zaszyfrowanego na obiekt JSON:

{
    "alg": "HS256",
    "typ": "JWT"
}.{
    "sub": "1234567890",
    "name": "Bugspace",
    "iat": 1516239022
}.HMACSHA256(
    base64UrlEncode(header) + "." +
    base64UrlEncode(payload),
    28BCCC274AD2F9EEDC51C3FCC33A1
)

Header

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

Jest w nim zawarta informacja o używanym algorytmie oraz typie tokenu. Do najczęściej używanych algorytmów kryptograficznych należy HMAC z SHA-256 (HS256) oraz podpis RSA z SHA-256 (RS256). JWT nie ogranicza się i możliwe jest wykorzystanie innych rodzajów algorytmów. Są one dostępne pod tym linkiem.

Payload

{
    "sub": "1234567890",
    "name": "Bugspace",
    "iat": 1516239022
}

Część JWT odpowiedzialna za przechowywanie danych przesyłanych na serwer. Umieszczane w nim są np informacje o dacie ważności tokenu czy roli użytkownika na stronie. Zarówno payload, jak i header, są kodowane w formacie Base64.

Signature

HMACSHA256(
    base64UrlEncode(header) + "." +
    base64UrlEncode(payload),
    28BCCC274AD2F9EEDC51C3FCC33A1
)

Ostanim elementem składającym się na budowę JWT jest sygnatura, mająca na celu potwierdzenie autentyczności przesyłanego tokenu. Zakładając, że używamy do haszowania algorytmu HMAC SHA256, to nasza sygnatura będzie utworzona na podstawie poniższego kodu.

signature = HMACSHA256(
    base64UrlEncode(header) + "." +
    base64UrlEncode(payload),
    secret
)

Oznacza to dla nas, że nie znając sekretu, każda zmiana w tokenie będzie nieautoryzowana. Nie będziemy mogli, przykładowo, zmienić uprawnień użytkownika w naszym payloadzie.

Błędy bezpieczeństwa

Stosowanie JWT wiąże się jednak z pewnymi ograniczeniami oraz, jak w każdym przypadku, z szeregiem podatności. Do najważniejszych problemów należy możliwość złamania algorytmu HS256 (HMAC-SHA256), potencjalny problem z implementacją z użyciem algorytmu asymetrycznego np. RS256 czy też nadmierna kompilacja spowodowana min. mnogością algorytmów. O tych i pokrewnych tematach wyczerpujących zagadnienie JWT, odsyłamy na ebook od sekuraka oraz bloga opisującego opisane min. wyżej opisane podatności.

Źródła

https://jwt.io/
https://tools.ietf.org/html/rfc7518
https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/
https://sekurak.pl/jwt-security-ebook.pdf

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.