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
nonezostá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ú
kidajku, menia overovanie podpisu na injekčný povrch. - Platný podpis nehovorí nič o platnosti claimov -
exp,issaaudmusia byť vynútené pri každej požiadavke. - Access tokeny držte v pamäti a refresh tokeny v cookies s príznakmi
HttpOnly,SecureaSameSite- nikdy nie vlocalStorage.
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.
{ "alg": "HS256", "typ": "JWT" }
{ "sub": "andrej", "role": "hacker" }
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:
- 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.
- 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/namesignalizujú 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": falsealebo"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
localStorageajsessionStorage, 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,SecureaSameSite, č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:
- Útočník získa verejný kľúč servera, často úplne triviálne, z JWKS endpointu.
- Upraví payload tokenu - napríklad si zvýši oprávnenia z
"role": "user"na"role": "admin". - Zmení hlavičku z
"alg": "RS256"na"alg": "HS256". - Znova podpíše celý upravený token (hlavičku aj payload), pričom ako HS256 tajomstvo použije verejný kľúč.
- Server token prijme, uvidí
alg: HS256a overí ho pomocou verejného kľúča ako HMAC tajomstva. Podpis sedí a podvrhnutý token je akceptovaný.
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
jkutak, 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
kidvkladá 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čipermissions, 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
nonealebo 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 algoritmusnoneodmietajte 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) aaud(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
localStorageanisessionStorage, 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íznakmiHttpOnlyaSameSite.
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:
- Autorizačný server vydá klientskej aplikácii náhodný, nepriehľadný reťazec relácie (namiesto JWT).
- Keď klient posiela API požiadavku, odošle tento nepriehľadný reťazec.
- 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.
- 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:
- PortSwigger Web Security Academy. JWT Security Vulnerabilities. Podrobný rozbor chýb pri overovaní podpisu a injekcií do hlavičky. portswigger.net/web-security/jwt
- InfoSec Writeups. JWT Pentesting: A Journey from Token to Takeover. Praktické prípadové štúdie zneužitia konfigurácie tokenov. infosecwriteups.com
- Auth0 / JWT.io. Introduction to JSON Web Tokens. Základná štandardizačná dokumentácia k štruktúre tokenov a RFC 7519. jwt.io/introduction
- JWTAuditor. Security Testing Tool. Používaný na manipuláciu s payloadom a automatizované posúdenie zraniteľností. jwtauditor.com