JWT (JSON Web Token)
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 (.):
- Header: Contains metadata about the token
- Payload: Contains the claims (statements about the entity)
- 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
- Registered claims: Predefined claims (e.g.,
- 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
Authorizationheader) - 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
| Algorithm | Description | Security Level |
|---|---|---|
| HS256 | HMAC with SHA-256 (symmetric) | Medium |
| HS384 | HMAC with SHA-384 (symmetric) | High |
| HS512 | HMAC with SHA-512 (symmetric) | High |
| RS256 | RSA with SHA-256 (asymmetric) | High |
| RS384 | RSA with SHA-384 (asymmetric) | High |
| RS512 | RSA with SHA-512 (asymmetric) | High |
| ES256 | ECDSA with P-256 and SHA-256 (asymmetric) | High |
| ES384 | ECDSA with P-384 and SHA-384 (asymmetric) | High |
| ES512 | ECDSA with P-521 and SHA-512 (asymmetric) | High |
| PS256 | RSASSA-PSS with SHA-256 (asymmetric) | High |
| PS384 | RSASSA-PSS with SHA-384 (asymmetric) | High |
| PS512 | RSASSA-PSS with SHA-512 (asymmetric) | High |
| none | No signature (insecure, should never be used in production) | None |
JWT Security Considerations
1. Algorithm Confusion Attacks
- Attackers change the algorithm to
noneto 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
| Feature | JWT | Session Cookies |
|---|---|---|
| State | Stateless | Stateful (server-side storage) |
| Scalability | High (no server-side storage) | Medium (requires server storage) |
| Performance | Fast (no database lookups) | Slower (requires database lookups) |
| Security | Vulnerable to theft | Vulnerable to CSRF |
| Revocation | Difficult (requires short expiration) | Easy (delete server-side session) |
| Use Case | APIs, microservices, SPAs | Traditional web apps |
JWT Libraries
| Language | Library |
|---|---|
| JavaScript | jsonwebtoken |
| Python | PyJWT |
| Java | jjwt |
| Go | jwt-go |
| Ruby | jwt |
| PHP | firebase/php-jwt |
| .NET | System.IdentityModel.Tokens.Jwt |
| Rust | jsonwebtoken |
JWT Attack Examples
1. CVE-2015-9235 (Algorithm Confusion)
- Attackers change
algfromRS256toHS256and 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
- JWT.io: Decode, verify, and generate JWTs
- jwt.ms: Microsoft's JWT debugger
- jwt.calebb.net: JWT debugger with algorithm support
- jwt-tool: Security testing tool for JWTs
Further Reading
JSON Web Token (JWT) Attacks
JWT attacks exploit vulnerabilities in JSON Web Token implementation and validation to bypass authentication, escalate privileges, or access sensitive data by manipulating token signatures, payloads, or algorithms.
Local File Inclusion (LFI)
Local File Inclusion (LFI) is a web security vulnerability that allows attackers to include files from the server filesystem, potentially leading to information disclosure, remote code execution, and complete system compromise.
