Komplexní průvodce osvědčenými postupy pro zabezpečení JWT (JSON Web Token), zahrnující validaci, ukládání, podepisovací algoritmy a strategie pro zmírnění běžných zranitelností v mezinárodních aplikacích.
JWT tokeny: Bezpečnostní osvědčené postupy pro globální aplikace
JSON Web Tokeny (JWT) se staly standardní metodou pro bezpečnou reprezentaci tzv. claims (tvrzení) mezi dvěma stranami. Jejich kompaktní struktura, snadné použití a široká podpora na různých platformách z nich učinily populární volbu pro autentizaci a autorizaci v moderních webových aplikacích, API a mikroslužbách. Jejich široké přijetí však také vedlo ke zvýšené kontrole a odhalení řady bezpečnostních zranitelností. Tento komplexní průvodce zkoumá osvědčené postupy zabezpečení JWT, aby vaše globální aplikace zůstaly bezpečné a odolné vůči potenciálním útokům.
Co jsou JWT a jak fungují?
JWT je bezpečnostní token založený na formátu JSON, který se skládá ze tří částí:
- Hlavička (Header): Specifikuje typ tokenu (JWT) a použitý podepisovací algoritmus (např. HMAC SHA256 nebo RSA).
- Tělo (Payload): Obsahuje tzv. claims (tvrzení), což jsou výroky o entitě (obvykle uživateli) a další metadata. Claims mohou být registrované (např. vydavatel, předmět, čas vypršení platnosti), veřejné (definované aplikací) nebo soukromé (vlastní claims).
- Podpis (Signature): Vytvoří se spojením zakódované hlavičky, zakódovaného těla, tajného klíče (pro algoritmy HMAC) nebo soukromého klíče (pro algoritmy RSA/ECDSA), specifikovaného algoritmu a podepsáním výsledku.
Tyto tři části jsou zakódovány pomocí Base64 URL a spojeny tečkami (.
) do výsledného řetězce JWT. Když se uživatel autentizuje, server vygeneruje JWT, který si klient následně uloží (typicky v local storage nebo cookie) a zahrne do následných požadavků. Server poté validuje JWT pro autorizaci požadavku.
Porozumění běžným zranitelnostem JWT
Než se ponoříme do osvědčených postupů, je klíčové porozumět běžným zranitelnostem spojeným s JWT:
- Záměna algoritmu (Algorithm Confusion): Útočníci zneužívají možnost změnit parametr
alg
v hlavičce ze silného asymetrického algoritmu (jako RSA) na slabý symetrický algoritmus (jako HMAC). Pokud server použije veřejný klíč jako tajný klíč v algoritmu HMAC, útočníci mohou padělat JWT. - Vyzrazení tajného klíče: Pokud je kompromitován tajný klíč použitý k podepisování JWT, mohou útočníci generovat platné JWT a vydávat se za jakéhokoli uživatele. To se může stát kvůli únikům kódu, nebezpečnému uložení nebo zranitelnostem v jiných částech aplikace.
- Krádež tokenu (XSS/CSRF): Pokud jsou JWT uloženy nebezpečně, útočníci je mohou ukrást prostřednictvím útoků Cross-Site Scripting (XSS) nebo Cross-Site Request Forgery (CSRF).
- Opakované útoky (Replay Attacks): Útočníci mohou znovu použít platné JWT k získání neoprávněného přístupu, zejména pokud mají tokeny dlouhou životnost a nejsou implementována žádná specifická protiopatření.
- Útoky typu Padding Oracle: Když jsou JWT šifrovány určitými algoritmy a tzv. padding (výplň) je nesprávně zpracován, útočníci mohou potenciálně dešifrovat JWT a získat přístup k jeho obsahu.
- Problémy s časovým posunem (Clock Skew): V distribuovaných systémech může časový posun mezi různými servery vést k selhání validace JWT, zejména u tvrzení o expiraci.
Bezpečnostní osvědčené postupy pro JWT
Zde jsou komplexní bezpečnostní osvědčené postupy pro zmírnění rizik spojených s JWT:
1. Volba správného podepisovacího algoritmu
Volba podepisovacího algoritmu je klíčová. Zde je, co zvážit:
- Vyhněte se
alg: none
: Nikdy nedovolte, aby byl parametralg
v hlavičce nastaven nanone
. Tím se vypne ověření podpisu, což komukoli umožní vytvářet platné JWT. Mnoho knihoven bylo opraveno, aby tomu zabránily, ale ujistěte se, že vaše knihovny jsou aktuální. - Preferujte asymetrické algoritmy (RSA/ECDSA): Kdykoli je to možné, používejte algoritmy RSA (RS256, RS384, RS512) nebo ECDSA (ES256, ES384, ES512). Asymetrické algoritmy používají soukromý klíč k podepisování a veřejný klíč k ověřování. To brání útočníkům v padělání tokenů, i když získají přístup k veřejnému klíči.
- Bezpečně spravujte soukromé klíče: Ukládejte soukromé klíče bezpečně pomocí hardwarových bezpečnostních modulů (HSM) nebo systémů pro bezpečnou správu klíčů. Nikdy neumisťujte soukromé klíče do repozitářů zdrojového kódu.
- Pravidelně rotujte klíče: Implementujte strategii rotace klíčů pro pravidelnou změnu podepisovacích klíčů. Tím se minimalizuje dopad, pokud by byl klíč někdy kompromitován. Zvažte použití JSON Web Key Sets (JWKS) k publikování vašich veřejných klíčů.
Příklad: Použití JWKS pro rotaci klíčů
Endpoint JWKS poskytuje sadu veřejných klíčů, které lze použít k ověření JWT. Server může rotovat klíče a klienti mohou automaticky aktualizovat svou sadu klíčů načtením endpointu JWKS.
/.well-known/jwks.json
:
{
"keys": [
{
"kty": "RSA",
"kid": "key1",
"alg": "RS256",
"n": "...",
"e": "AQAB"
},
{
"kty": "RSA",
"kid": "key2",
"alg": "RS256",
"n": "...",
"e": "AQAB"
}
]
}
2. Správná validace JWT
Správná validace je nezbytná k prevenci útoků:
- Ověřte podpis: Vždy ověřte podpis JWT pomocí správného klíče a algoritmu. Ujistěte se, že vaše knihovna pro JWT je správně nakonfigurována a aktuální.
- Validujte claims: Validujte základní claims jako
exp
(čas expirace),nbf
(platné ne dříve než),iss
(vydavatel) aaud
(cílová skupina). - Zkontrolujte claim
exp
: Ujistěte se, že platnost JWT nevypršela. Implementujte rozumnou životnost tokenu, abyste minimalizovali časové okno pro útočníky. - Zkontrolujte claim
nbf
: Ujistěte se, že JWT není používán před začátkem jeho platnosti. To brání opakovaným útokům před zamýšleným použitím tokenu. - Zkontrolujte claim
iss
: Ověřte, že JWT byl vydán důvěryhodným vydavatelem. To brání útočníkům v používání JWT vydaných neoprávněnými stranami. - Zkontrolujte claim
aud
: Ověřte, že JWT je určen pro vaši aplikaci. To brání tomu, aby JWT vydané pro jiné aplikace byly použity proti vaší. - Implementujte seznam zamítnutí (volitelné): Pro kritické aplikace zvažte implementaci seznamu zamítnutí (také známého jako seznam odvolaných tokenů) k zneplatnění kompromitovaných JWT před jejich expirací. To přidává na složitosti, ale může výrazně zlepšit bezpečnost.
Příklad: Validace claims v kódu (Node.js s jsonwebtoken
)
const jwt = require('jsonwebtoken');
try {
const decoded = jwt.verify(token, publicKey, {
algorithms: ['RS256'],
issuer: 'https://example.com',
audience: 'https://myapp.com'
});
console.log(decoded);
} catch (error) {
console.error('Validace JWT selhala:', error);
}
3. Bezpečné ukládání JWT na straně klienta
Způsob, jakým jsou JWT ukládány na straně klienta, významně ovlivňuje bezpečnost:
- Vyhněte se Local Storage: Ukládání JWT v local storage je činí zranitelnými vůči útokům XSS. Pokud útočník dokáže vložit JavaScript do vaší aplikace, může snadno ukrást JWT z local storage.
- Používejte HTTP-Only cookies: Ukládejte JWT do HTTP-only cookies s atributy
Secure
aSameSite
. K HTTP-only cookies nelze přistupovat pomocí JavaScriptu, což zmírňuje rizika XSS. AtributSecure
zajišťuje, že cookie je přenášena pouze přes HTTPS. AtributSameSite
pomáhá předcházet útokům CSRF. - Zvažte refresh tokeny: Implementujte mechanismus refresh tokenů. Krátkodobé přístupové tokeny se používají pro okamžitou autorizaci, zatímco dlouhodobé refresh tokeny se používají k získání nových přístupových tokenů. Ukládejte refresh tokeny bezpečně (např. v databázi se šifrováním).
- Implementujte ochranu proti CSRF: Při použití cookies implementujte mechanismy ochrany proti CSRF, jako jsou synchronizační tokeny nebo vzor Double Submit Cookie.
Příklad: Nastavení HTTP-Only cookies (Node.js s Expressem)
app.get('/login', (req, res) => {
// ... logika autentizace ...
const token = jwt.sign({ userId: user.id }, privateKey, { expiresIn: '15m' });
const refreshToken = jwt.sign({ userId: user.id }, refreshPrivateKey, { expiresIn: '7d' });
res.cookie('accessToken', token, {
httpOnly: true,
secure: true, // V produkci nastavit na true
sameSite: 'strict', // nebo 'lax' v závislosti na vašich potřebách
maxAge: 15 * 60 * 1000 // 15 minut
});
res.cookie('refreshToken', refreshToken, {
httpOnly: true,
secure: true, // V produkci nastavit na true
sameSite: 'strict',
maxAge: 7 * 24 * 60 * 60 * 1000 // 7 dní
});
res.send({ message: 'Přihlášení úspěšné' });
});
4. Ochrana proti útokům záměnou algoritmu
Záměna algoritmu je kritická zranitelnost. Zde je, jak jí předejít:
- Explicitně specifikujte povolené algoritmy: Při ověřování JWT explicitně specifikujte povolené podepisovací algoritmy. Nespoléhejte se na to, že knihovna JWT automaticky určí algoritmus.
- Nedůvěřujte hlavičce
alg
: Nikdy slepě nedůvěřujte hlavičcealg
v JWT. Vždy ji validujte proti předdefinovanému seznamu povolených algoritmů. - Používejte silné statické typování (pokud je to možné): V jazycích, které podporují statické typování, vynucujte přísnou kontrolu typů pro parametry klíče a algoritmu.
Příklad: Prevence záměny algoritmu (Node.js s jsonwebtoken
)
const jwt = require('jsonwebtoken');
try {
const decoded = jwt.verify(token, publicKey, {
algorithms: ['RS256'] // Explicitně povolit pouze RS256
});
console.log(decoded);
} catch (error) {
console.error('Validace JWT selhala:', error);
}
5. Implementace správné expirace tokenů a mechanismů pro jejich obnovu
Životnost tokenu je klíčovým bezpečnostním hlediskem:
- Používejte krátkodobé přístupové tokeny: Udržujte přístupové tokeny krátkodobé (např. 5-30 minut). Tím se omezí dopad, pokud je token kompromitován.
- Implementujte refresh tokeny: Používejte refresh tokeny k získání nových přístupových tokenů, aniž by se uživatel musel znovu autentizovat. Refresh tokeny mohou mít delší životnost, ale měly by být bezpečně uloženy.
- Implementujte rotaci refresh tokenů: Rotujte refresh tokeny pokaždé, když je vydán nový přístupový token. Tím se zneplatní starý refresh token, což omezuje potenciální škody, pokud je refresh token kompromitován.
- Zvažte správu sezení: Pro citlivé aplikace zvažte implementaci správy sezení na straně serveru navíc k JWT. To vám umožní odvolat přístup granulárněji.
6. Ochrana proti krádeži tokenů
Prevence krádeže tokenů je zásadní:
- Implementujte přísnou Content Security Policy (CSP): Použijte CSP k prevenci útoků XSS. CSP vám umožňuje specifikovat, které zdroje mohou načítat prostředky (skripty, styly, obrázky atd.) na vašem webu.
- Sanitizujte uživatelský vstup: Sanitizujte veškerý uživatelský vstup, abyste předešli útokům XSS. Použijte důvěryhodnou knihovnu pro sanitizaci HTML k ošetření potenciálně škodlivých znaků.
- Používejte HTTPS: Vždy používejte HTTPS k šifrování komunikace mezi klientem a serverem. Tím se brání útočníkům v odposlouchávání síťového provozu a krádeži JWT.
- Implementujte HSTS (HTTP Strict Transport Security): Použijte HSTS k instruování prohlížečů, aby vždy používaly HTTPS při komunikaci s vaším webem.
7. Monitorování a logování
Efektivní monitorování a logování jsou nezbytné pro detekci a reakci na bezpečnostní incidenty:
- Logujte vydávání a validaci JWT: Logujte všechny události vydávání a validace JWT, včetně ID uživatele, IP adresy a časového razítka.
- Monitorujte podezřelou aktivitu: Monitorujte neobvyklé vzorce, jako jsou vícenásobné neúspěšné pokusy o přihlášení, JWT používané z různých míst současně nebo rychlé požadavky na obnovení tokenu.
- Nastavte upozornění: Nastavte upozornění, která vás informují o potenciálních bezpečnostních incidentech.
- Pravidelně kontrolujte logy: Pravidelně kontrolujte logy k identifikaci a vyšetřování podezřelé aktivity.
8. Omezení četnosti požadavků (Rate Limiting)
Implementujte omezení četnosti požadavků (rate limiting), abyste předešli útokům hrubou silou a útokům typu denial-of-service (DoS):
- Omezte pokusy o přihlášení: Omezte počet neúspěšných pokusů o přihlášení z jedné IP adresy nebo uživatelského účtu.
- Omezte požadavky na obnovení tokenu: Omezte počet požadavků na obnovení tokenu z jedné IP adresy nebo uživatelského účtu.
- Omezte požadavky na API: Omezte počet požadavků na API z jedné IP adresy nebo uživatelského účtu.
9. Udržování aktuálnosti
- Udržujte knihovny aktuální: Pravidelně aktualizujte své JWT knihovny a závislosti, abyste opravili bezpečnostní zranitelnosti.
- Dodržujte bezpečnostní osvědčené postupy: Zůstaňte informováni o nejnovějších bezpečnostních osvědčených postupech a zranitelnostech souvisejících s JWT.
- Provádějte bezpečnostní audity: Pravidelně provádějte bezpečnostní audity vaší aplikace k identifikaci a řešení potenciálních zranitelností.
Globální aspekty bezpečnosti JWT
Při implementaci JWT pro globální aplikace zvažte následující:
- Časová pásma: Ujistěte se, že vaše servery jsou synchronizovány se spolehlivým časovým zdrojem (např. NTP), abyste se vyhnuli problémům s časovým posunem, které mohou ovlivnit validaci JWT, zejména claims
exp
anbf
. Zvažte konzistentní používání časových značek v UTC. - Předpisy o ochraně osobních údajů: Mějte na paměti předpisy o ochraně osobních údajů, jako jsou GDPR, CCPA a další. Minimalizujte množství osobních údajů uložených v JWT a zajistěte soulad s příslušnými předpisy. V případě potřeby šifrujte citlivé claims.
- Internacionalizace (i18n): Při zobrazování informací z JWT claims zajistěte, aby byla data správně lokalizována pro jazyk a region uživatele. To zahrnuje správné formátování dat, čísel a měn.
- Právní soulad: Buďte si vědomi jakýchkoli právních požadavků souvisejících s ukládáním a přenosem dat v různých zemích. Zajistěte, aby vaše implementace JWT byla v souladu se všemi platnými zákony a předpisy.
- Cross-Origin Resource Sharing (CORS): Nakonfigurujte správně CORS, aby vaše aplikace mohla přistupovat k prostředkům z různých domén. To je zvláště důležité při použití JWT pro autentizaci napříč různými službami nebo aplikacemi.
Závěr
JWT nabízejí pohodlný a efektivní způsob, jak řešit autentizaci a autorizaci, ale také přinášejí potenciální bezpečnostní rizika. Dodržováním těchto osvědčených postupů můžete výrazně snížit riziko zranitelností a zajistit bezpečnost vašich globálních aplikací. Nezapomeňte se informovat o nejnovějších bezpečnostních hrozbách a podle toho aktualizovat svou implementaci. Upřednostňování bezpečnosti během celého životního cyklu JWT pomůže chránit vaše uživatele a data před neoprávněným přístupem.