← Terug naar blog

JWT exp/iat/nbf Fouten: tijdclaim-bugs die de authenticatie verbreken

Beveiliging voor ontwikkelaars27 maart 2026·8 min leestijd
JWT time claims debugging

JWT tijdclaims — exp, iat en nbf — zijn bedrieglijk eenvoudig. Het zijn gewoon Unix-tijdstempels. Toch veroorzaken ze een aantal van de meest frustrerende authenticatiefouten in de productie: tokens die te snel verlopen, tokens die op de ene server werken maar niet op een andere, en tokens die helemaal nooit verlopen.

Dit artikel behandelt de meest voorkomende tijdclaimbugs, waarom ze optreden en hoe je ze kunt oplossen met veilige standaardinstellingen.

Hoe exp, iat en nbf werken

Elke JWT kan drie tijdgerelateerde claims in zijn payload meenemen:

Alle drie zijn numerieke datums: het aantal seconden sinds 1970-01-01T00:00:00Z (Unix-tijdperk). Geen milliseconden – seconden. Dit onderscheid alleen al veroorzaakt grofweg 20% van alle JWT-tijdbugs.

Gebruik onze JWT-decoder om tijdclaims in elk token onmiddellijk te inspecteren.

Bug #1: Milliseconden gebruiken in plaats van seconden

JavaScript's Date.now() retourneert milliseconden. De JWT-specificatie vereist seconden. Door exp in te stellen op Date.now() + 3600000 wordt een token gemaakt dat vervalt in het jaar 2089, niet binnen één uur.

// FOUT — milliseconden
const exp = Datum.nu() + 3600000; // CORRECT — seconden
const exp = Math.floor(Datum.nu() / 1000) + 3600;

De meeste JWT-bibliotheken verwerken dit intern, maar als u handmatig payloads samenstelt, is dit het eerste dat u moet controleren.

Bug #2: exp-claim volledig ontbreken

Als u vergeet exp in te stellen, zullen veel bibliotheken graag een token maken dat nooit verloopt. Dit is een veiligheidsrisico: een gelekt token blijft voor altijd geldig.

Stel altijd exp in. Valideer het altijd op de server. Als uw bibliotheek standaard tokens zonder exp niet afwijst, configureert u dit zo.

// Node.js jsonwebtoken — vervaldatum afdwingen
jwt.verify(token, geheim, { maxAge: '1h' });

Bug #3: Klokafwijking tussen servers

Server A geeft een token uit om 14:00:00 uur. De klok van server B geeft 13:59:55 aan (5 seconden achter). Als het token nbf: 1711540800 (14:00:00) heeft, wijst Server B het af als "nog niet geldig."

Dit komt vooral veel voor in:

De oplossing

Laat een kleine kloktolerantie toe (ook wel 'speelruimte' genoemd) — doorgaans 30-60 seconden:

// jsonwebtoken
jwt.verify(token, geheim, { clockTolerance: 30 }); // jose (Node.js)
wachten jwtVerify(token, sleutel, { clockTolerance: '30s' });

Stel de tolerantie nooit boven de 2 minuten in. Als je meer nodig hebt, repareer dan je NTP-synchronisatie.

Bug #4: Verkeerde validatiebestelling

De juiste validatievolgorde is belangrijk. Als je de handtekening controleert nadat je de vervaldatum hebt gecontroleerd, kan een aanvaller een token maken met een toekomstige exp die de tijdscontrole doorstaat maar een ongeldige handtekening heeft.

Veilige validatiebestelling:

  1. Decodeer header (controleer algoritme)
  2. Handtekening verifiëren
  3. Controleer exp (weigeren indien verlopen)
  4. Controleer nbf (afwijzen indien nog niet geldig)
  5. Controleer iat (afwijzen indien onredelijk oud)
  6. Controleer de uitgever, doelgroep en andere claims

De meeste goed onderhouden bibliotheken gaan hier correct mee om, maar aangepaste middleware gaat vaak fout.

Bug #5: Tijdzoneverwarring in iat

JWT-tijdstempels zijn altijd UTC. Maar ontwikkelaars maken ze soms op basis van lokale tijd:

// FOUT — lokale tijdzone
const iat = new Date('2026-03-27T14:00:00').getTime() / 1000; // CORRECT — expliciete UTC
const iat = new Date('2026-03-27T14:00:00Z').getTime() / 1000;

Zonder het achtervoegsel Z interpreteert JavaScript de tekenreeks in de lokale tijdzone, waardoor de tijdstempel uren kan verschuiven.

Bug #6: Tokens accepteren zonder nbf-controle

De claim nbf is handig voor tokens voor vertraagde activering, bijvoorbeeld een token dat alleen zou moeten werken na een geplande implementatie. Als uw validator nbf negeert, kunnen deze tokens worden gebruikt vóór de beoogde activeringstijd.

De meeste bibliotheken valideren nbf standaard, maar verifieer dit in uw configuratie, vooral met aangepaste middleware.

Bug #7: te lange vervaldatum

Het instellen van exp op 30 dagen voor een toegangstoken verslaat het doel van tokens met een korte levensduur. Beste praktijken:

Voor veilige vernieuwingstokenpatronen raadpleegt u onze handleiding over JWT vernieuwingstokenrotatie.

Testcases die elke API zou moeten hebben

Voeg deze toe aan je testpakket om bugs in tijdclaims vroegtijdig op te sporen:

  1. Token met exp in het verleden → 401
  2. Token met exp precies nu → 401 (grens)
  3. Token zonder exp → 401
  4. Token met nbf in de toekomst → 401
  5. Token met nbf iets in de toekomst (binnen tolerantie) → 200
  6. Token met iat in de toekomst → 401 (duidt op geknoei)
  7. Token met tijdstempels in milliseconden → 401 (detecteert de ms/s-bug)

Veilige standaardinstellingen voor populaire frameworks

Node.js (jsonwebtoken)

jwt.sign(payload, geheim, { expiresIn: '15m' });
jwt.verify(token, geheim, { clockTolerance: 30, maxAge: '15m'
});

Python (PyJWT)

jwt.decode(token, sleutel, algoritmen=['HS256'], speelruimte=tijddelta(seconden=30), opties={'require': ['exp', 'iat']})

Ga (golang-jwt)

parser := jwt.NewParser( jwt.WithLeeway(30 * tijd.Seconde), jwt.WithValidMethods([]string{"HS256"}),
)

Veelgestelde vragen

Moet dit verplicht zijn?

Hoewel de JWT-specificatie zegt dat iat optioneel is, helpt het verplicht stellen ervan bij het opsporen van fouten en audittrails. Zonder iat kunt u niet bepalen wanneer een token is gemaakt, waardoor het moeilijker wordt om te correleren met beveiligingsgebeurtenissen.

Hoeveel klokafwijking moet ik toestaan?

Een veel voorkomende veilige standaardwaarde is 30-60 seconden. Langer dan 2 minuten introduceert beveiligingsrisico's. Als uw systemen meer nodig hebben, corrigeer dan de NTP-synchronisatie in plaats van de scheefheidslimiet te vergroten.

Welke HTTP-statuscode moet ik retourneren voor een verlopen token?

Retourneer 401 Ongeautoriseerd met een duidelijke fouttekst zoals {"error": "token_expired"}. Retourneer niet 403 Verboden - dit impliceert dat het token geldig is maar geen machtigingen heeft, wat een andere situatie is.

Gerelateerde tools en artikelen