1. The Anatomy of a JWT (RFC 7519)
A JSON Web Token is a compact, URL-safe means of representing claims to be transferred between two parties. It consists of three parts separated by dots (.):
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c- Header: Identifies the token type (
JWT) and the cryptographic signing algorithm (HS256,RS256,ES256). - Payload (Claims): Contains the assertions about the entity (e.g., user ID, tenant, role permissions) and metadata (expiry, issuer).
- Signature: Calculated by hashing the encoded header, encoded payload, and a secret key or private key. Ensures the payload has not been tampered with.
*Note:* The header and payload are Base64URL-encoded, not encrypted. Anyone who intercepts a JWT can read its contents instantly with a decoder tool. Never place plaintext secrets, database passwords, or unencrypted credit card numbers in a JWT payload.
2. Standard Reserved Claims Deep Dive
RFC 7519 defines several standard 3-letter registered claim names:
| Claim | Full Name | Type | Description |
|---|---|---|---|
iss | Issuer | String | Identifies the principal that issued the JWT (e.g. https://auth.lintify.dev) |
sub | Subject | String | Unique identifier of the user or machine principal |
aud | Audience | String / Array | Identifies the recipients that the JWT is intended for |
exp | Expiration Time | NumericDate (Unix timestamp) | Absolute timestamp after which the token MUST NOT be accepted |
nbf | Not Before | NumericDate | Absolute timestamp before which the token MUST NOT be accepted |
iat | Issued At | NumericDate | Timestamp when the token was created |
jti | JWT ID | String (UUID) | Unique identifier for the token; used for replay attack prevention |
3. Cryptographic Signatures: HS256 vs RS256 vs EdDSA
Symmetric (HMAC with SHA-256 - HS256) * Uses a single shared secret key for both signing and verifying. * **Drawback:** Every microservice that needs to verify the token must know the shared secret. If one service is compromised, an attacker can forge tokens for all services.
Asymmetric (RSA / ECDSA / Ed25519 - RS256 / ES256 / EdDSA) * The Identity Provider (IdP) holds the **Private Key** and signs tokens. * All downstream microservices fetch the **Public Key** (often via a JSON Web Key Set `/.well-known/jwks.json`) to verify tokens. * **Security Benefit:** Downstream services cannot forge tokens even if their memory is dumped.
4. Critical JWT Security Pitfalls
1. The `"alg": "none"` Exploit Early vulnerable libraries allowed attackers to modify the header to `{"alg": "none"}` and strip the signature entirely, tricking backends into accepting unsigned forged admin tokens. * **Mitigation:** Explicitly whitelist permitted algorithms on the verifier (e.g., `algorithms: ['RS256']`).
2. Algorithm Confusion Attacks (HMAC vs RSA) An attacker takes the server's public RSA key (which is publicly accessible) and signs a forged token using HMAC-SHA256 with the public key as the symmetric secret string. If the backend validator accepts both algorithms, it verifies successfully. * **Mitigation:** Never allow dynamic algorithm determination based on the token header alone.
3. Missing Expiration Verification Never accept a JWT without verifying `exp`. Always include a small clock skew tolerance (e.g. 30 seconds) to handle server time drift.
5. Token Lifecycle, Refresh Tokens & Revocation
Because JWTs are stateless, revoking an access token before its natural exp time is difficult.
Recommended Architecture: 1. **Short-lived Access Tokens (5 to 15 minutes):** Kept in memory. 2. **Long-lived Refresh Tokens (7 to 30 days):** Stored in secure `HttpOnly`, `SameSite=Strict` cookies and tracked in a fast Redis revocation blocklist. 3. **Token Rotation:** Every time a refresh token is used, issue a new refresh token and invalidate the previous one immediately.
Lintify Engineering Team
Identity, Authentication & Cryptography
Lintify publishes in-depth engineering references for data format interoperability, stream processing, parser security, and API infrastructure. All tools on Lintify run purely browser-side with zero data collection.