JWT exp/iat/nbf Mistakes: Time-Claim Bugs that Break Auth

Časové nároky JWT —exp, iat, a nbf- sú klamlivo jednoduché. Sú to len časové pečiatky Unixu. Napriek tomu spôsobujú niektoré z najviac frustrujúcich chýb autentifikácie vo výrobe: tokeny, ktorých platnosť vyprší príliš skoro, tokeny, ktoré fungujú na jednom serveri, ale nie na inom, a tokeny, ktorých platnosť nikdy nevyprší.
Tento článok sa zaoberá najbežnejšími chybami pri nárokovaní času, prečo sa vyskytujú a ako ich opraviť pomocou bezpečných predvolených nastavení.
Ako fungujú exp, iat a nbf
Každý JWT môže mať vo svojom užitočnom zaťažení tri nároky súvisiace s časom:
- exp(Čas vypršania platnosti) — token NESMIE byť akceptovaný po tejto časovej pečiatke
- iat(Vydané v) — keď bol token vytvorený
- nbf(Nie predtým) — token NESMIE byť akceptovaný pred touto časovou pečiatkou
Všetky tri sú číselné dátumy: počet sekúnd od roku 1970-01-01T00:00:00Z (epocha Unixu). Nie milisekundy – sekundy. Toto rozlíšenie samo o sebe spôsobuje približne 20 % všetkých chýb v čase JWT.
Použite naše Dekodér JWT na okamžitú kontrolu časových nárokov v akomkoľvek tokene.
Chyba č. 1: Používanie milisekúnd namiesto sekúnd
JavaScript Date.now() vráti milisekundy. Špecifikácia JWT vyžaduje sekundy. Nastavenie exp do Date.now() + 3600000 vytvorí token, ktorého platnosť vyprší v roku 2089, nie o hodinu.
// ZLE — milisekúnd
const exp = Date.now() + 3600000; // SPRÁVNE — sekundy
const exp = Math.floor(Date.now() / 1000) + 3600;
Väčšina knižníc JWT to rieši interne, ale ak vytvárate užitočné zaťaženia manuálne, toto je prvá vec, ktorú treba skontrolovať.
Chyba č. 2: Chýbajúci nárok na celý experiment
Ak zabudnete nastaviť exp, mnohé knižnice s radosťou vytvoria token, ktorý nikdy nevyprší. Ide o bezpečnostné riziko: uniknutý token zostáva platný navždy.
Vždy nastavené exp. Vždy to overte na serveri. Ak vaša knižnica neodmietne tokeny bez exp v predvolenom nastavení ho tak nakonfigurujte.
// Node.js jsonwebtoken — vynúti uplynutie platnosti
jwt.verify(token, tajomstvo, { maxVek: '1h' }); Chyba č. 3: Prechyľovanie hodín medzi servermi
Server A vydá token o 14:00:00. Hodiny servera B ukazujú 13:59:55 (5 sekúnd pozadu). Ak má token nbf: 1711540800(14:00:00), server B ho odmietne ako „zatiaľ neplatné“.
Toto je bežné najmä v:
- Architektúry mikroservisov s nesynchronizovanými hodinami
- Bezserverové funkcie, kde kontajnery majú časový posun
- Mobilné aplikácie, kde sa hodiny zariadenia nastavujú manuálne
Oprava
Nechajte malú tolerancia hodín(nazýva sa aj „voľnosť“) – zvyčajne 30 – 60 sekúnd:
// jsonwebtoken
jwt.verify(token, tajomstvo, { tolerancia hodín: 30 }); // jose (Node.js)
wait jwtVerify(token, kľúč, { tolerancia hodín: '30s' });
Nikdy nenastavujte toleranciu nad 2 minúty. Ak potrebujete viac, opravte si synchronizáciu NTP.
Chyba č. 4: Nesprávny príkaz na overenie
Dôležité je správne poradie overenia. Ak skontrolujete podpis po skontrolovaní vypršania platnosti, útočník môže vytvoriť token s budúcnosťou exp ktorý prešiel časovou kontrolou, ale má neplatný podpis.
Bezpečná overovacia objednávka:
- Dekódovať hlavičku (skontrolovať algoritmus)
- Overte podpis
- Skontrolujte
exp(odmietnuť, ak platnosť vypršala) - Skontrolujte
nbf(odmietnuť, ak ešte nie je platný) - Skontrolujte
iat(odmietnuť, ak je neprimerane starý) - Skontrolujte vydavateľa, publikum a ďalšie nároky
Väčšina dobre udržiavaných knižníc to rieši správne, ale vlastný middleware to často robí zle.
Chyba č. 5: Zmätok v časovom pásme v IAT
Časové pečiatky JWT sú vždy UTC. Vývojári ich však niekedy vytvárajú pomocou miestneho času:
// WRONG — miestne časové pásmo
const iat = new Date('2026-03-27T14:00:00').getTime() / 1000; // SPRÁVNE — explicitné UTC
const iat = new Date('2026-03-27T14:00:00Z').getTime() / 1000;
Bez toho Z prípona, JavaScript interpretuje reťazec v miestnom časovom pásme, čo môže posunúť časovú pečiatku o hodiny.
Chyba č. 6: Prijímanie tokenov bez kontroly nbf
The nbf claim je užitočný pre tokeny s oneskorenou aktiváciou – napríklad token, ktorý by mal fungovať až po naplánovanom nasadení. Ak váš validátor ignoruje nbf, tieto tokeny možno použiť pred plánovaným časom aktivácie.
Väčšina knižníc overuje nbf predvolene, ale overte si to vo svojom nastavení, najmä pomocou vlastného middlewaru.
Chyba č. 7: Príliš dlhá doba platnosti
Nastavenie exp na 30 dní v prípade, že prístupový token porušuje účel tokenov s krátkou životnosťou. Osvedčené postupy:
- Prístupové tokeny: 5–15 minút
- Obnoviť tokeny: 7-30 dní (s rotáciou)
- ID tokeny: 1 hodina
Vzory bezpečných obnovovacích tokenov nájdete v našom sprievodcovi Rotácia obnovovacieho tokenu JWT.
Testovacie prípady, ktoré by malo mať každé API
Pridajte tieto do svojho testovacieho balíka, aby ste včas zachytili chyby súvisiace s nárokom na čas:
- Token s
expv minulosti → 401 - Token s
exppresne teraz → 401 (hranica) - Token s č
exp→ 401 - Token s
nbfv budúcnosti → 401 - Token s
nbfmierne v budúcnosti (v rámci tolerancie) → 200 - Token s
iatv budúcnosti → 401 (označuje manipuláciu) - Token s milisekundovými časovými pečiatkami → 401 (deteguje chybu ms/s)
Bezpečné predvolené nastavenia pre populárne rámce
Node.js (jsonwebtoken)
jwt.sign(užitočné zaťaženie, tajné, { expiresIn: '15m' });
jwt.verify(token, tajomstvo, { Tolerancia hodín: 30, maxVek: '15m'
});
Python (PyJWT)
jwt.decode(token, kľúč, algoritmy=['HS256'], leeway=timedelta(sekundy=30), options={'require': ['exp', 'iat']})
Choď (golang-jwt)
syntaktický analyzátor := jwt.NewParser( jwt.WithLeeway(30 * krát.Second), jwt.WithValidMethods([]string{"HS256"}),
) FAQ
Malo by to byť povinné?
Zatiaľ čo špecifikácia JWT hovorí iat je voliteľný, vďaka čomu je povinný pomáha pri ladení a auditovaní. Bez iat, nemôžete určiť, kedy bol token vytvorený, čo sťažuje koreláciu s bezpečnostnými udalosťami.
Aký veľký posun hodín by som mal povoliť?
Bežné bezpečné predvolené nastavenie je 30–60 sekúnd. Viac ako 2 minúty predstavuje bezpečnostné riziko. Ak vaše systémy potrebujú viac, opravte synchronizáciu NTP namiesto rozšírenia povolenej odchýlky.
Aký stavový kód HTTP by som mal vrátiť pre token, ktorého platnosť vypršala?
Návrat 401 Neoprávnené s jasným telom chyby {"error": "token_expired"}. Nevracať 403 Zakázané – to znamená, že token je platný, ale nemá povolenia, čo je iná situácia.
Súvisiace nástroje a články
- Dekodér JWT— kontrolovať časové nároky v akomkoľvek tokene
- Bezpečnostné chyby JWT— širšie úskalia JWT nad rámec časových nárokov
- Obnoviť rotáciu tokenu— bezpečný vzor pre dlhodobé sedenia
- Sprievodca 2FA— pridať druhú vrstvu za tokeny