JWT tokeny: Hĺbkový pohľad na bezpečnosť, zraniteľnosti a najlepšie postupy


JSON Web Tokeny (JWT) sú dnes de facto štandardom pre bezstavovú autentifikáciu v moderných webových aplikáciách. Ich flexibilita však veľmi často vedie k fatálnym chybám v konfigurácii. Keď penetrační testeri uvidia JWT, nevidia iba identifikátor relácie - vidia kryptografický útočný povrch.

Kľúčové poznatky

  • JWT je zakódovaný, nie zašifrovaný - každý claim v payloade si prečíta ktokoľvek, kto token drží v rukách.
  • Zámena algoritmov (RS256 na HS256) a algoritmus none zostávajú najzávažnejšími chybami podpisu, aké nachádzame vo vlastných a starších implementáciách.
  • HS256 tajomstvá sú heslá. Zachytený token sa dá prelomiť offline nástrojom Hashcat, bez akejkoľvek ďalšej interakcie s cieľom.
  • Parametre hlavičky dodané klientom, ako sú kid a jku, menia overovanie podpisu na injekčný povrch.
  • Platný podpis nehovorí nič o platnosti claimov - exp, iss a aud musia byť vynútené pri každej požiadavke.
  • Access tokeny držte v pamäti a refresh tokeny v cookies s príznakmi HttpOnly, Secure a SameSite - nikdy nie v localStorage.

Anatómia JWT: hlavička, payload a podpis

JWT sa skladá z troch častí: z hlavičky, payloadu a podpisu, ktoré sú oddelené bodkou (.). Pre pentestera vyzerá zachytený JWT ako dlhý reťazec zdanlivo náhodných znakov. Tu je príklad z reálnej praxe:

eyJraWQiOiI5MTM2ZGRiMy1jYjBhLTRhMTktYTA3ZS1lYWRmNWE0NGM4YjUiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsImV4cCI6MTY0ODAzNzE2NCwibmFtZSI6IkNhcmxvcyBNb250b3lhIiwic3ViIjoiY2FybG9zIiwicm9sZSI6ImJsb2dfYXV0aG9yIiwiZW1haWwiOiJjYXJsb3NAY2FybG9zLW1vbnRveWEubmV0IiwiaWF0IjoxNTE2MjM5MDIyfQ.SYZBPIBg2CRjXAJ8vCER0LA_ENjII1JakvNQoP-Hw6GG1zfl4JyngsZReIfqRvIAEi5L4HV0q7_9qGhQZvy9ZdxEJbwTxRs_6Lb-fZTDpW6lKYNdMyjw45_alSCZ1fypsMWz_2mTpQzil0lOtps5Ei_z7mM7M8gCwe_AGpI53JxduQOaB5HkT5gVrv9cKu9CsW5MS6ZbqYXpGyOG5ehoxqm8DL5tFYaW3lB50ELxi0KsuTKEbD0t5BCl0aCR2MBJWAbN-xeLwEenaqBiwPVvKixYleeDQiBEIylFdNNIMviKRgXiYuAvMziVPbwSgkZVHeEdF5MQP1Oe2Spac-6IfA

Hlavička a payload sú iba JSON objekty zakódované pomocou Base64Url. Sú teda len zakódované, nie zašifrované. Ktokoľvek, kto sa k tokenu dostane, si tieto dáta dokáže dekódovať a prečítať.

Vizualizácia štruktúry JWT

JWT (technicky presnejšie JWS - JSON Web Token „v podpísanej podobe“) sa skladá z troch častí oddelených bodkou: Header.Payload.Signature.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhbmRyZWoiLCJyb2xlIjoiaGFja2VyIn0.MmM0ZGMxM2Y1NWQ2YTY2YTE
Hlavička · algoritmus & typ tokenu
{ "alg": "HS256", "typ": "JWT" }
Payload · dáta
{ "sub": "andrej", "role": "hacker" }
Podpis
HMACSHA256(
    base64UrlEncode(header) + "." +
    base64UrlEncode(payload),
    "secret"
) = MmM0ZGMxM2Y1NWQ2YTY2YTE

Hlavička

Hlavička obsahuje metadáta o samotnom tokene, predovšetkým typ tokenu a kryptografický algoritmus použitý na jeho zabezpečenie. Dekódovanie prvej časti tokenu vyššie odhalí:

{
    "kid": "9136ddb3-cb0a-4a19-a07e-eadf5a44c8b5",
    "alg": "RS256"
}

Payload

Payload obsahuje samotné tvrdenia („claims“) o používateľovi. Práve toto je pri bezpečnostnom posúdení hlavný cieľ manipulácie. Dekódovanie strednej časti nášho príkladu odhalí:

{
    "iss": "portswigger",
    "exp": 1648037164,
    "name": "Andrej Šebeň",
    "sub": "andrej",
    "role": "pentester",
    "email": "[email protected]",
    "iat": 1516239022
}

Podpis

Keďže hlavičku aj payload si dokáže ktokoľvek jednoducho prečítať alebo upraviť, bezpečnosť každého mechanizmu postaveného na JWT stojí a padá na kryptografickom podpise.

Server, ktorý token vydáva, zahašuje hlavičku a payload zakódované pomocou Base64Url tajným podpisovým kľúčom. Tento mechanizmus zaručuje dve veci:

  1. Keďže je podpis priamo odvodený od zvyšku tokenu, zmena čo i len jedného bajtu hlavičky alebo payloadu vedie k nesúhlasnému podpisu.
  2. Bez znalosti tajného podpisového kľúča servera by nemalo byť možné vygenerovať správny podpis pre podvrhnutú hlavičku alebo payload.

Čo v JWT hľadajú útočníci

Keďže sú JWT už zo svojej podstaty čitateľné, útočníci ich nevnímajú ako zašifrované dáta, ale ako cenný zdroj informácií pri prieskume. Z útočného pohľadu sa logické chyby najčastejšie skrývajú práve v payloade. Toto sú kritické claimy, ktoré si prezeráme ako prvé:

Claim Účel Čo pri pentestoch overujeme
iss (Issuer - vydavateľ) Identifikuje toho, kto token vydal. Overuje to backend naozaj? Systém, ktorý akceptuje tokeny vydané neoprávnenou treťou stranou, je zraniteľný voči zámene tokenov.
sub (Subject - subjekt) Používateľ alebo entita, ktorú token reprezentuje, často ID používateľa. Nezabezpečený priamy odkaz na objekt (IDOR). Dokážeme to zmeniť na admin alebo user_id=1 a obísť tak autorizáciu?
aud (Audience - príjemca) Identifikuje zamýšľaného príjemcu tokenu. Dá sa token vydaný pre jednu mikroslužbu prehrať voči úplne inej, vysoko privilegovanej mikroslužbe?
exp (Expiration Time - expirácia) Unixová časová značka, kedy platnosť tokenu vyprší. Vynucuje to server naozaj? Pravidelne nachádzame API, ktoré akceptujú expirované tokeny donekonečna.
nbf (Not Before - platný najskôr od) Čas, pred ktorým nesmie byť token akceptovaný. Vo validačnej logike býva veľmi často úplne vynechaný.
iat (Issued At - čas vydania) Kedy bol token vytvorený. Užitočný na výpočet životnosti tokenov a na odhalenie tokenov, ktoré sa nikdy nerotujú.

Prieskum payloadu: zlatá baňa na únik informácií

Keďže payload vidí ktokoľvek, kto token drží v rukách, vývojári by ho mali považovať za verejnú informáciu. Pri posúdeniach opakovane nachádzame zbytočné interné detaily vystavené vo vlastných claimoch:

  • Mapovanie internej siete: vlastné claimy ako "node_ip": "10.0.4.12", "cluster": "prod-us-east-1a" či "db_host": "internal-db.local" prezrádzajú architektúru internej siete a rozsahy IP adries.
  • Únik informácií o frameworku a poskytovateľovi identity: konvencie pomenovania claimov prezradia použitý technologický stack. Claimy ako http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name signalizujú backend postavený na Microsoft .NET / Entra ID, čo nám umožní zamerať sa na zraniteľnosti špecifické pre daný stack.
  • Osobné údaje (PII): zbytočné vystavenie e-mailov, telefónnych čísel, celých mien alebo fyzických adries používateľov - čím okamžite vzniká porušenie právnych predpisov (GDPR / CCPA).
  • Enumerácia tenantov a rolí: claimy ako "tenant_id": "uuid", "is_god_mode": false alebo "permissions": ["read:profile"] odhaľujú autorizačnú schému a dávajú nám presné názvy parametrov, na ktoré sa zameriame pri eskalácii oprávnení.

Príklad „ukecaného“ JWT payloadu zachyteného v reálnej prevádzke:

{
  "iss": "auth.internal-corp.local",
  "sub": "usr_99812",
  "email": "[email protected]",
  "role": "admin",
  "internal_ip": "10.240.12.88",
  "db_shard": "shard-04-eu",
  "is_admin": true,
  "exp": 1748037164
}

Bearer tokeny verzus refresh tokeny: architektúra a ukladanie

Bezpečná implementácia JWT stojí na systéme dvoch tokenov: krátkodobých access tokenov (bearer tokenov) a dlhodobých refresh tokenov. Ich nesprávne ukladanie je vôbec najčastejšia zraniteľnosť, ktorú reportujeme.

Bearer tokeny (access tokeny)

  • Access tokeny autorizujú API požiadavky a sú zámerne krátkodobé, spravidla s platnosťou 5 až 15 minút.
  • Ukladajte ich výhradne do pamäte aplikácie. Vyhnite sa localStorage aj sessionStorage, pretože ich útočníkovi môže sprístupniť akákoľvek úspešne zneužitá XSS zraniteľnosť.

Refresh tokeny

  • Refresh tokeny slúžia výlučne na získanie nových access tokenov po ich expirácii.
  • Mali by byť uložené v cookies s príznakmi HttpOnly, Secure a SameSite, čo znemožní prístup z JavaScriptu a výrazne zníži riziko krádeže tokenu cez XSS, pričom zároveň pomáha zmierniť CSRF.

Príručka pentestera: najčastejšie útoky na JWT

Pri audite webovej aplikácie prechádzajú penetračné tímy spravidla nasledujúce útočné vektory.

A. Zlyhania pri overovaní podpisu

Množstvo zraniteľností JWT nevzniká z prelomenej kryptografie, ale z nesprávneho overovania podpisu. Historicky niektoré knižnice akceptovali algoritmus none, čo útočníkom umožnilo podpis úplne odstrániť a ľubovoľne meniť claimy, napríklad používateľské role. Všetky významné moderné knižnice none vo východiskovom nastavení odmietajú, no táto chyba sa stále objavuje v starších aplikáciách a vo vlastných implementáciách JWT - a oplatí sa ju otestovať vždy, keď narazíte na neštandardný stack.

Ďalším klasickým problémom je zámena algoritmov (algorithm confusion). Ide o jednu z najzávažnejších zraniteľností JWT a oplatí sa jej rozumieť do detailu.

  • RS256 je asymetrický algoritmus. Server podpisuje tokeny svojím súkromným kľúčom a overuje ich zodpovedajúcim verejným kľúčom. Verejný kľúč býva často voľne dostupný - napríklad vystavený na endpointe /.well-known/jwks.json.
  • HS256 je symetrický algoritmus. Server používa na podpisovanie aj overovanie tokenov jedno spoločné tajomstvo.

Útok zneužíva situáciu, keď server akceptuje oba algoritmy bez toho, aby mal natvrdo určené, ktorý z nich očakáva:

  1. Útočník získa verejný kľúč servera, často úplne triviálne, z JWKS endpointu.
  2. Upraví payload tokenu - napríklad si zvýši oprávnenia z "role": "user" na "role": "admin".
  3. Zmení hlavičku z "alg": "RS256" na "alg": "HS256".
  4. Znova podpíše celý upravený token (hlavičku aj payload), pričom ako HS256 tajomstvo použije verejný kľúč.
  5. Server token prijme, uvidí alg: HS256 a overí ho pomocou verejného kľúča ako HMAC tajomstva. Podpis sedí a podvrhnutý token je akceptovaný.
Útok zámenou algoritmov na JWT: zmena hlavičky alg z RS256 na HS256 a opätovné podpísanie tokenu verejným kľúčom servera ako HMAC tajomstvom

Príčinou nie je prelomená kryptografia - je ňou server, ktorý slepo dôveruje hlavičke alg dodanej klientom, keď rozhoduje o tom, ako má token overiť. Za bežných okolností by zmena alg v hlavičke podpis znehodnotila, keďže podpis pokrýva hlavičku aj payload. Útočník však celý upravený token podpíše nanovo, takže nový podpis je pri zamenenom algoritme dokonale platný.

Moderné knižnice tieto chyby do veľkej miery odstránili, no v starších aplikáciách a vo vlastných implementáciách JWT sa stále objavujú.

B. Slabé podpisové tajomstvá

Aplikácie, ktoré používajú symetrické algoritmy ako HS256, sú presne také bezpečné, ako je tajomstvo použité na podpísanie tokenu.

Počas penetračného testu sa dá zachytený JWT napadnúť úplne offline nástrojmi ako Hashcat alebo John the Ripper. Slabé tajomstvá, ako sú názvy firiem, slovníkové slová či predvídateľné frázy, bývajú prelomené v priebehu minút, čo útočníkovi umožní generovať platné tokeny pre ľubovoľného používateľa bez toho, aby s cieľovou aplikáciou ešte raz komunikoval.

C. Injekcia cez parametre hlavičky

Hlavičky JWT môžu obsahovať voliteľné parametre ako kid (Key ID) a jku (JWK Set URL), ktoré serveru pomáhajú určiť, ktorý podpisový kľúč sa má pri overovaní použiť. Keďže tieto hodnoty dodáva klient, ich dôverovanie bez riadnej validácie môže priniesť vážne zraniteľnosti.

Medzi bežné útočné vektory patria:

  • manipulácia parametra jku tak, aby odkazoval na JWKS endpoint ovládaný útočníkom;
  • zneužitie prechodu adresárovou štruktúrou (directory traversal) cez parameter kid, ak sa kľúče načítavajú priamo zo súborového systému;
  • zneužitie SQL injection tam, kde sa hodnota kid vkladá reťazením priamo do databázových dopytov.

Vyzreté JWT knižnice si s týmito scenármi poradia bezpečne, no vlastná overovacia logika naďalej produkuje nálezy pri bezpečnostných posúdeniach.

D. Zlyhania pri validácii claimov

Platný podpis automaticky neznamená, že sa dá tokenu dôverovať. Aplikácia musí validovať aj každý bezpečnostne významný claim.

Počas pentestov pravidelne narážame na API, ktoré:

  • akceptujú expirované tokeny, pretože ignorujú claim exp;
  • nevalidujú zamýšľaného príjemcu (aud), čím umožnia prehrávanie tokenov medzi rôznymi službami;
  • dôverujú ľubovoľným hodnotám vydavateľa (iss);
  • sa spoliehajú výhradne na claimy ovládané klientom, ako sú role, tenant či permissions, bez vynútenia autorizácie na strane servera.

Tieto logické chyby mávajú v praxi väčší dopad než kryptografické slabiny, pretože umožňujú použiť legitímne tokeny spôsobom, na ktorý neboli určené.

Moderné nástroje na testovanie bezpečnosti JWT

Ručné dekódovanie Base64 a manipulácia s podpismi sú neefektívne. Pentesteri sa pri automatizácii týchto útokov spoliehajú na špecializované nástroje:

  • JWTAuditor: vynikajúca platforma na bezpečnostné testovanie, ktorá beží na strane klienta a je šitá na mieru pentesterom. Umožňuje rýchlu inšpekciu, automatizovanú detekciu zraniteľností (napríklad testovanie algoritmu none alebo injekcií do hlavičky) a offline lámanie hrubou silou bez rizika, že sa citlivé zákaznícke tokeny dostanú do telemetrie tretích strán.
  • Burp Suite (rozšírenie JWT Editor): intenzívne sa využíva pri dynamickom testovaní webu na úpravu tokenov za behu počas zachytávania HTTP komunikácie cez proxy.
  • JWT.io: udržiavaný spoločnosťou Auth0, je štandardným nástrojom na rýchle manuálne dekódovanie a na overenie štruktúry a podpisu tokenu počas úvodného prieskumu.
  • JWTLens: odľahčená alternatíva na inšpekciu tokenov s dôrazom na súkromie. Dekóduje a overuje tokeny výhradne v prehliadači pomocou natívneho Web Crypto API, takže vaše tokeny a kľúče nikdy neopustia váš počítač. Keďže pri overovaní neprebiehajú žiadne sieťové požiadavky, ide o ideálny nástroj na bezpečné overovanie algoritmov a podpisov.

Praktické obranné odporúčania

Aby sa vaša aplikácia nedostala medzi kritické nálezy v pentest reporte, vývojové tímy by mali vynútiť tieto základné opatrenia:

  • Natvrdo určte očakávané algoritmy: nikdy nenechajte prichádzajúci token rozhodovať o tom, ako sa má overiť. Explicitne nastavte validačnú rutinu tak, aby očakávala konkrétny algoritmus (napríklad RS256), a algoritmus none odmietajte bez výnimky.
  • Vynúťte plnú validáciu claimov: platný podpis dokazuje len to, že token nebol pozmenený; neznamená, že je pre daného používateľa aktuálne platný. Explicitne validujte exp (expiráciu), iss (vydavateľa) a aud (príjemcu) pri každej jednej požiadavke.
  • K symetrickým tajomstvám pristupujte ako k heslám: ak si vaša architektúra vyžaduje symetrické podpisovanie (HS256), váš tajný kľúč je v podstate root heslo. Zabezpečte, aby mal minimálnu entropiu 256 bitov, aby bol vygenerovaný kryptograficky bezpečným generátorom náhodných čísel a aby bol bezpečne uložený v premenných prostredia alebo v správcovi tajomstiev - nikdy nie natvrdo v zdrojovom kóde.
  • Pamätajte: kódovanie nie je šifrovanie. Nikdy neukladajte do payloadu JWT citlivé údaje, osobné údaje ani heslá. Ktokoľvek, kto token zachytí, si ho okamžite dekóduje z Base64.
  • Izolujte ukladanie tokenov: nikdy neukladajte krátkodobé access tokeny do localStorage ani sessionStorage, kde ich dokáže odcudziť jediná XSS zraniteľnosť. Access tokeny držte striktne v pamäti na strane klienta a dlhodobé refresh tokeny umiestnite do bezpečných cookies s príznakmi HttpOnly a SameSite.

Pokročilé zabezpečenie: vzor phantom token

V prostrediach s vysokými nárokmi na bezpečnosť je najúčinnejšou obranou proti krádeži na strane klienta vôbec nevystaviť JWT frontendu. Moderné podnikové architektúry preto často implementujú vzor „phantom token“ v týchto krokoch:

  1. Autorizačný server vydá klientskej aplikácii náhodný, nepriehľadný reťazec relácie (namiesto JWT).
  2. Keď klient posiela API požiadavku, odošle tento nepriehľadný reťazec.
  3. API brána požiadavku zachytí, overí nepriehľadný token voči autentifikačnému serveru (alebo úložisku relácií) a vymení ho za plnohodnotný, podpísaný JWT.
  4. API brána následne posunie skutočný JWT interným mikroslužbám.

Často kladené otázky o bezpečnosti JWT

01

Je JWT šifrovaný?

Nie. Hlavička a payload štandardného podpísaného JWT (teda JWS) sú iba zakódované pomocou Base64Url, nie zašifrované. Ktokoľvek, kto token drží v rukách, si dokáže dekódovať a prečítať každý claim v ňom. Podpis chráni integritu, nie dôvernosť, takže do payloadu JWT nepatria žiadne citlivé údaje ani osobné údaje.

02

Čo je zámena algoritmov (algorithm confusion) pri JWT?

Zámena algoritmov nastáva vtedy, keď server nechá o spôsobe overenia podpisu rozhodnúť samotnú hlavičku alg v tokene. Útočník vezme verejný RSA kľúč servera, prepíše hlavičku z RS256 na HS256, upraví payload a celý token znova podpíše, pričom ako HMAC tajomstvo použije práve tento verejný kľúč. Server, ktorý akceptuje oba algoritmy, takýto podvrh úspešne overí. Riešením je natvrdo určiť očakávaný algoritmus na strane servera.

03

Kde majú byť v prehliadači uložené access a refresh tokeny?

Krátkodobé access tokeny držte výhradne v pamäti aplikácie. Dlhodobé refresh tokeny ukladajte do cookies s príznakmi HttpOnly, Secure a SameSite, aby ich JavaScript nedokázal prečítať. Ani jeden z týchto tokenov nikdy neukladajte do localStorage ani sessionStorage, kde ich dokáže odcudziť jediná XSS zraniteľnosť.

04

Ako útočníci prelamujú podpisové tajomstvá HS256?

Zachytený HS256 token sa dá napadnúť úplne offline nástrojmi ako Hashcat alebo John the Ripper, bez akejkoľvek ďalšej interakcie s cieľovou aplikáciou. Slabé tajomstvá, ako sú názvy firiem, slovníkové slová či predvídateľné frázy, padnú často v priebehu minút a útočník si následne dokáže vygenerovať platný token pre ľubovoľného používateľa. Symetrické tajomstvá potrebujú aspoň 256 bitov entropie z kryptograficky bezpečného generátora.

05

Znamená platný podpis, že sa dá JWT dôverovať?

Nie. Platný podpis dokazuje len to, že token nebol pozmenený. Aplikácia musí naďalej validovať každý bezpečnostne významný claim: exp pre expiráciu, iss pre vydavateľa, aud pre zamýšľaného príjemcu - a nikdy sa nesmie spoliehať na claimy dodané klientom, ako sú role alebo permissions, bez vynútenia autorizácie na strane servera.

Ako môže pomôcť Haxoris

Bezpečnosť tokenov málokedy padne na kryptografii - padne na konfigurácii. Haxoris vám pomôže nájsť tieto medzery skôr, než ich nájde útočník:

  • Penetračné testovanie webových aplikácií a API s osobitným zameraním na procesy autentifikácie a autorizácie.
  • Revízia logiky vydávania a overovania JWT a správy kľúčov vrátane práce s JWKS a rotácie kľúčov.
  • Offline posúdenie sily symetrických podpisových tajomstiev.
  • Revízia návrhu ukladania tokenov, životnosti relácií a architektúry refresh tokenov.

Záver

JWT nie sú nebezpečné zo svojej podstaty. Nebezpečnými sa stávajú vo chvíli, keď aplikácia nechá o spôsobe validácie rozhodnúť samotný token alebo keď platný podpis považuje za náhradu autorizácie. Natvrdo určte algoritmus, validujte každý claim, k tajomstvám sa správajte ako k root heslám a tokeny nenechávajte v úložisku prehliadača - a väčšina nálezov z tohto článku sa vo vašom ďalšom pentest reporte vôbec neobjaví.

Zdroje a odporúčaná literatúra

Metodiky a technické detaily v tomto článku sú inšpirované nasledujúcimi odbornými bezpečnostnými zdrojmi a vychádzajú z nich:

  1. PortSwigger Web Security Academy. JWT Security Vulnerabilities. Podrobný rozbor chýb pri overovaní podpisu a injekcií do hlavičky. portswigger.net/web-security/jwt
  2. InfoSec Writeups. JWT Pentesting: A Journey from Token to Takeover. Praktické prípadové štúdie zneužitia konfigurácie tokenov. infosecwriteups.com
  3. Auth0 / JWT.io. Introduction to JSON Web Tokens. Základná štandardizačná dokumentácia k štruktúre tokenov a RFC 7519. jwt.io/introduction
  4. JWTAuditor. Security Testing Tool. Používaný na manipuláciu s payloadom a automatizované posúdenie zraniteľností. jwtauditor.com
Pavol Litauszki

Autor

Pavol Litauszki

Nečakajte na útočníkov – odhaľte svoje najslabšie miesto s penetračným testom už teraz!

Rezervovať