JWT (JSON Web Token)

Learn about JSON Web Tokens (JWT), the compact, URL-safe standard for securely transmitting information between parties as JSON objects.

What is a JWT?

JSON Web Token (JWT) is an open standard (RFC 7519) for securely transmitting information between parties as a JSON object. JWTs are compact, URL-safe, and can be digitally signed or encrypted to ensure integrity and confidentiality. They are widely used for authentication and authorization in modern web applications.

JWT Structure

A JWT consists of three parts separated by dots (.):

  1. Header: Contains metadata about the token
  2. Payload: Contains the claims (statements about the entity)
  3. Signature: Ensures the token hasn't been tampered with
Header.Payload.Signature

Example JWT

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

1. Header

  • Specifies the token type (JWT) and signing algorithm (e.g., HS256, RS256)
  • Example:
    {
      "alg": "HS256",
      "typ": "JWT"
    }
    

2. Payload

  • Contains claims (statements about the user and additional data)
  • Three types of claims:
    • Registered claims: Predefined claims (e.g., iss, exp, sub)
    • Public claims: Custom claims defined in the IANA registry
    • Private claims: Custom claims agreed upon by parties
  • Example:
    {
      "sub": "1234567890",
      "name": "John Doe",
      "iat": 1516239022,
      "exp": 1516242622,
      "admin": true
    }
    

3. Signature

  • Created by combining the encoded header, encoded payload, and a secret
  • Ensures the token hasn't been altered
  • Example (HMAC-SHA256):
    HMACSHA256(
      base64UrlEncode(header) + "." + base64UrlEncode(payload),
      secret
    )
    

JWT Use Cases

1. Authentication

  • After successful login, the server issues a JWT
  • Client includes the JWT in subsequent requests (e.g., in the Authorization header)
  • Example:
    Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
    

2. Authorization

  • JWTs can contain permissions and roles
  • Example payload:
    {
      "sub": "user123",
      "roles": ["admin", "editor"],
      "permissions": ["read:data", "write:data"]
    }
    

3. Information Exchange

  • Securely transmit data between parties
  • Example: Sharing user profile data between microservices

JWT Algorithms

AlgorithmDescriptionSecurity Level
HS256HMAC with SHA-256 (symmetric)Medium
HS384HMAC with SHA-384 (symmetric)High
HS512HMAC with SHA-512 (symmetric)High
RS256RSA with SHA-256 (asymmetric)High
RS384RSA with SHA-384 (asymmetric)High
RS512RSA with SHA-512 (asymmetric)High
ES256ECDSA with P-256 and SHA-256 (asymmetric)High
ES384ECDSA with P-384 and SHA-384 (asymmetric)High
ES512ECDSA with P-521 and SHA-512 (asymmetric)High
PS256RSASSA-PSS with SHA-256 (asymmetric)High
PS384RSASSA-PSS with SHA-384 (asymmetric)High
PS512RSASSA-PSS with SHA-512 (asymmetric)High
noneNo signature (insecure, should never be used in production)None

JWT Security Considerations

1. Algorithm Confusion Attacks

  • Attackers change the algorithm to none to bypass signature verification
  • Mitigation: Always validate the algorithm and reject none

2. Weak Secrets

  • Symmetric algorithms (e.g., HS256) rely on a shared secret
  • Mitigation: Use strong secrets (e.g., 256-bit random strings)

3. Token Theft

  • Attackers steal JWTs to impersonate users
  • Mitigation: Use short-lived tokens and HTTPS

4. Insecure Storage

  • Storing JWTs in localStorage or sessionStorage (vulnerable to XSS)
  • Mitigation: Use HTTP-only, Secure, SameSite cookies

5. Overly Permissive Tokens

  • Tokens with excessive permissions or long expiration times
  • Mitigation: Use least privilege and short expiration times

6. Information Leakage

  • JWTs can contain sensitive data in the payload
  • Mitigation: Avoid storing sensitive data or encrypt the payload (JWE)

JWT Best Practices

1. Use Asymmetric Algorithms

  • Prefer RS256 or ES256 over symmetric algorithms
  • Enables public key verification without sharing secrets

2. Set Short Expiration Times

  • Access tokens: 15-60 minutes
  • Refresh tokens: 7-30 days (stored securely)
  • Example:
    {
      "exp": 1516242622, // 1 hour from now
      "iat": 1516239022
    }
    

3. Validate All Tokens

  • Verify the signature, issuer, audience, and expiration
  • Example (Node.js with jsonwebtoken):
    const jwt = require('jsonwebtoken');
    
    const verifyToken = (token, secret) => {
      try {
        const decoded = jwt.verify(token, secret, {
          algorithms: ['RS256'], // Only allow RS256
          audience: 'your-audience',
          issuer: 'your-issuer'
        });
        return decoded;
      } catch (err) {
        console.error('Invalid token:', err.message);
        return null;
      }
    };
    

4. Secure Token Storage

  • Store tokens in HTTP-only, Secure, SameSite cookies
  • Avoid localStorage (vulnerable to XSS)

5. Implement Token Revocation

  • Use short-lived tokens + refresh tokens
  • Maintain a revocation list for compromised tokens

6. Use JWT with OAuth 2.0/OIDC

  • JWTs are commonly used as access tokens and ID tokens in OAuth 2.0/OIDC
  • Example OIDC ID token:
    {
      "iss": "https://auth.example.com",
      "sub": "user123",
      "aud": "your-client-id",
      "exp": 1516242622,
      "iat": 1516239022,
      "nonce": "random-nonce"
    }
    

7. Encrypt Sensitive Data (JWE)

  • Use JSON Web Encryption (JWE) for sensitive payloads
  • Example JWE header:
    {
      "alg": "RSA-OAEP-256",
      "enc": "A256GCM"
    }
    

JWT vs. Session Cookies

FeatureJWTSession Cookies
StateStatelessStateful (server-side storage)
ScalabilityHigh (no server-side storage)Medium (requires server storage)
PerformanceFast (no database lookups)Slower (requires database lookups)
SecurityVulnerable to theftVulnerable to CSRF
RevocationDifficult (requires short expiration)Easy (delete server-side session)
Use CaseAPIs, microservices, SPAsTraditional web apps

JWT Libraries

JWT Attack Examples

1. CVE-2015-9235 (Algorithm Confusion)

  • Attackers change alg from RS256 to HS256 and sign with the public key
  • Impact: Bypasses signature verification
  • Mitigation: Always validate the algorithm and reject none

2. CVE-2018-0114 (Key Injection)

  • Attackers inject a malicious key into the JWT header
  • Impact: Allows arbitrary token signing
  • Mitigation: Only allow predefined keys and validate headers

3. CVE-2020-28042 (Null Signature)

  • Attackers set the signature to an empty string
  • Impact: Bypasses signature verification in some libraries
  • Mitigation: Always validate the signature and reject empty signatures

JWT Debugging Tools

Further Reading