Kategori: Story

  • JWT-parserguide: Slik dekoder, validerer og inspiserer du JSON Web Tokens trygt

    JWT-parserguide: Slik dekoder, validerer og inspiserer du JSON Web Tokens trygt

    Autentiseringen din akkurat knekt i produksjon. Brukere får feilmeldingen «Invalid Token», og du må finne ut hvorfor — raskt. Du åpner JWT-en, og den ser ut som rein volapyk: tre blokker med tilfeldige tegn adskilt av punktum. Dataene ligger der inne, men du kan ikke lese dem uten en parser.

    En JWT-parser er et spesialisert verktøy som bryter ned de tre delene av et JSON Web Token — Header, Payload og Signature — i henhold til RFC 7519-standarden. Per april 2026 dekoder disse parserne Base64URL-kodede data og verifiserer signaturer ved hjelp av secrets eller offentlige nøkler for å sikre at tokenet ikke har blitt manipulert, og blokkerer dermed trusler som «alg: none»-angrepet.

    Hva en JWT-parser faktisk gjør

    Tenk på en JWT-parser som en oversetter. Den tar en lang, uleselig streng og gjør den om til lesbare JSON-objekter igjen. Dette er grunnleggende for å administrere brukeridentiteter og sikre datautveksling i moderne applikasjoner.

    Internt finner parseren de to punktumene (.) som deler tokenet inn i tre seksjoner:

    Seksjon Formål Kodet? Lesbar uten nøkkel?
    Header Metadata: signeringsalgoritme (HS256, RS256) Base64URL Ja
    Payload Claims: brukerdata, utløp, roller Base64URL Ja
    Signature Digitalt segl som beviser ekthet HMAC/RSA Nei — krever nøkkel

    Forenklet 3-dels struktur for et JWT-token

    Dekoding trinn for trinn: Hva som skjer inni

    La oss spore gjennom et ekte token. Ta denne eksempel-JWT-en:

    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4iLCJpYXQiOjE3MDAwMDAwMDB9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
    

    Trinn 1: Splitt på punktum

    [0] eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
    [1] eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4iLCJpYXQiOjE3MDAwMDAwMDB9
    [2] SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
    

    Trinn 2: Base64URL-dekod seksjon [0] (Header)

    {
      "alg": "HS256",
      "typ": "JWT"
    }
    

    Trinn 3: Base64URL-dekod seksjon [1] (Payload)

    {
      "sub": "1234567890",
      "name": "John",
      "iat": 1700000000
    }
    

    Trinn 4: Verifiser seksjon [2] (Signature) — krever secret-nøkkelen

    Parseren tar den Base64URL-kodede headeren + «.» + payload, og beregner deretter en HMAC-SHA256 ved hjelp av secreten. Hvis resultatet samsvarer med seksjon [2], er tokenet ekte.

    Kritisk sikkerhetsnotat: Base64URL er ikke kryptering

    En vanlig felle for nyere utviklere er å anta at den kodede headeren og payloaden er kryptert. Det er de ikke. Som JustUse.me påpeker, gjør Base64URL-koding bare JSON trygt å sende gjennom URL-er og headere. Hvem som helst som har tokenet kan dekode payloaden uten passord eller nøkkel.

    Lagre aldri sensitive data (passord, fødselsnumre, API-nøkler) i en JWT-payload. De er synlige for alle som fanger opp tokenet.

    Signaturverifikasjon: Sikkerhetsporten

    Mens hvem som helst kan lese et tokens data, er det signaturverifikasjon som faktisk holder systemet ditt sikkert. En JWT-parser leser ikke bare informasjon — den beviser hvor den kommer fra.

    Parseren beregner signaturen på nytt ved hjelp av header, payload og en nøkkel, og sjekker deretter om resultatet samsvarer med signaturen på tokenet. Hvis de ikke stemmer overens, har tokenet blitt manipulert.

    To algoritmefamilier

    Algoritme Nøkkeltype Hvordan det fungerer Vanlig brukstilfelle
    HS256 (HMAC) Symmetrisk — samme secret-nøkkel for signering og verifikasjon Begge parter deler én secret Autentisering for én tjeneste, mikrotjenester innen ett team
    RS256 (RSA) Asymmetrisk — privat nøkkel signerer, offentlig nøkkel verifiserer Avsender beholder privat nøkkel; alle med offentlig nøkkel kan verifisere OAuth2-leverandører, tredjeparts API-integrasjoner
    ES256 (ECDSA) Asymmetrisk — samme modell som RSA, men med elliptiske kurver Mindre nøkler, raskere verifikasjon Mobilapper, ytelsesfølsomme tjenester

    3-trinns verifikasjonslogikk for en JWT-parser

    «alg: none»-angrepet

    Dette er en av de farligste JWT-sårbarhetene. En angriper endrer headeren til å angi "alg": "none" og fjerner signaturen. En dårlig implementert parser kan akseptere dette og behandle tokenet som gyldig uten noen som helst verifikasjon.

    Forsvar: Parseren din må eksplisitt avvise ethvert token der algoritmen er «none» eller ikke samsvarer med den forventede algoritmen. Stas Persiianenko, som utviklet Apify JWT-verktøyet, understreker at mens tokens er gjennomsiktige ved design, avhenger sikkerheten deres av at parseren strengt avviser usignerte eller manipulerte tokens.

    decoded = jwt.decode(token, key, algorithms=None)  # NEVER do this
    
    decoded = jwt.decode(token, key, algorithms=["HS256"])
    

    Standard JWT-claims: Hvert enkelt felt og dets betydning

    En JWT-parser trekker ut «claims» fra payloaden. Disse følger JOSE (JSON Object Signing and Encryption)-rammeverket for kompatibilitet på tvers av systemer.

    Claim Fullt navn Formål Eksempelverdi
    iss Issuer Hvem som utstedte tokenet "auth.example.com"
    sub Subject Brukeren eller enheten tokenet representerer "user:12345"
    aud Audience Tiltenkt mottaker av tokenet "api.example.com"
    exp Expiration Time Når tokenet blir ugyldig 1700000000 (Unix-tidsstempel)
    iat Issued At Når tokenet ble opprettet 1699999999
    nbf Not Before Tokenet er ikke gyldig før dette tidspunktet 1699999999
    jti JWT ID Unik identifikator for tokenet "a1b2c3d4"

    Når man bruker asymmetriske signaturer, refererer parserne ofte til en JWK (JSON Web Key) — en JSON-struktur som representerer en offentlig nøkkel. Parseren henter automatisk riktig JWK fra utstederens metadata-endepunkt for å verifisere tokenet.

    Implementering: Ekte kode for produksjon

    PHP med lcobucci/jwt

    Standarden i PHP-økosystemet er lcobucci/jwt. Data fra Packagist viser over 322 millioner installasjoner per april 2026, noe som gjør det til det foretrukne valget for Laravel- og Symfony-prosjekter.

    use Lcobucci\JWT\Configuration;
    use Lcobucci\JWT\Signer\Hmac\Sha256;
    use Lcobucci\JWT\Signer\Key\InMemory;
    
    $config = Configuration::forSymmetricSigner(
        new Sha256(),
        InMemory::plainText('your-secret-key')
    );
    
    // Parsing and validating a token
    $token = $config->parser()->parse($jwtString);
    
    // Verify constraints: expiration, issuer, etc.
    $constraints = [
        new \Lcobucci\JWT\Validation\Constraint\IssuedBy('auth.example.com'),
        new \Lcobucci\JWT\Validation\Constraint\PermittedFor('api.example.com'),
        new \Lcobucci\JWT\Validation\Constraint\SignedWith(
            $config->signer(),
            $config->signingKey()
        ),
    ];
    
    $isValid = $config->validator()->validate($token, ...$constraints);
    

    Hono (Edge/Serverless) med Web Crypto

    For lette edge-applikasjoner tilbyr Hono JWT Helper en minimal decode()-funksjon som er perfekt for serverless-plattformer der du vil ha raske cold starts og minimale avhengigheter.

    import { jwt } from 'hono/jwt'
    
    // Middleware to verify JWT on every request
    app.use('/api/*', jwt({ secret: 'your-secret' }))
    
    // Access decoded claims in your handler
    app.get('/api/profile', (c) => {
      const payload = c.get('jwtPayload')
      return c.json({ user: payload.sub })
    })
    

    AI-drevet JWT-analyse med MCP

    Fra og med 2026 lar Model Context Protocol (MCP) AI-assistenter som Claude Code eller Cursor kommunisere direkte med JWT-verktøy. Sett opp en MCP-server, og en utvikler kan be en AI om å «Sjekk alle JWT-er i disse loggene for utløpsfeil» — agenten håndterer parsingen via kommandolinjen.

    Ifølge Apify koster bulkbehandling rundt $11.50 per 10 000 tokens per 2026. Denne automatiseringen lar AI-agenter finne utløpte tokens og umiddelbart foreslå kodeendringer for appens sikkerhetsinnstillinger.

    Konklusjon

    En JWT-parser er mer enn en praktisk feilsøkingshjelp — den er et viktig sikkerhetskontrollpunkt. Den sikrer at tokens er ekte gjennom signaturkontroller og gyldige gjennom claim-verifikasjon. Husk de to reglene som betyr mest: Base64URL er ikke kryptering, så legg aldri hemmeligheter i payloaden. Og angi alltid eksplisitt tillatte algoritmer for å forhindre «alg: none»-angrep.

    For produksjonsapper bør du bruke utprøvde biblioteker som lcobucci/jwt eller Honos JWT-helper i stedet for å skrive din egen parser. For feilsøking og bulkanalyse er AI-drevne MCP-verktøy den moderne tilnærmingen for å holde sikkerhetsrevisjoner automatiserte og grundige.

    FAQ

    Er det lov å dekode et JWT-token jeg fant i nettleseren min?

    Ja, det er helt lovlig. JWT-er er designet for å være gjennomsiktige — headeren og payloaden er kodet for transport, ikke kryptert for hemmelighold. Å besitte tokenet innebærer at du har tilgang til dataene i dets claims. Imidlertid må du alltid følge lokale personvernlover som GDPR når tokens inneholder personopplysninger.

    Hvorfor viser JWT-parseren min isExpired: true for et token jeg akkurat genererte?

    Dette skyldes vanligvis klokkeskjevhet (clock drift) mellom serveren som genererte tokenet og systemet som parser det. Hvis de to systemenes klokker ikke er synkronisert (via UTC/NTP), kan exp– eller nbf-claims virke ugyldige. Løs dette ved å sikre at begge systemene bruker NTP for tidssynkronisering, eller legg til en liten «slak» (vanligvis 60 seconds) i parserbiblioteket ditt for å ta høyde for mindre avvik.

    Kan jeg dekode en JWT uten å ha secret eller offentlig nøkkel?

    Ja, du kan alltid dekode og lese Header og Payload uten en nøkkel, fordi de bare er Base64URL-kodet JSON. Du kan imidlertid ikke verifisere Signaturen eller stole på at dataene er ekte uten tilsvarende secret (for HS256) eller offentlig nøkkel (for RS256). Uten verifikasjon bør du behandle dataene som uverifiserte og potensielt manipulerte.

    Hva er «alg: none»-angrepet og hvordan forhindrer jeg det?

    «alg: none»-angrepet utnytter parserne som aksepterer algoritmen angitt i token-headeren uten validering. En angriper endrer headeren til "alg": "none" og fjerner signaturen, noe som lurer en sårbar parser til å akseptere tokenet som gyldig. Forhindre dette ved alltid å eksplisitt angi tillatte algoritmer i verifiseringskoden din — aksepter aldri «none» eller la tokenet diktere hvilken algoritme som skal brukes.