Three segments, one dot each
A JSON Web Token is a compact, URL-safe representation of claims transferred between two parties. Its wire format is exactly three Base64URL-encoded strings joined by dots:
Each segment is independently readable. The header and payload are not encrypted in a standard JWT (JWS) - they are only Base64URL-encoded, meaning anyone who intercepts the token can read its claims without any key material. Only the signature provides integrity; confidentiality requires JWE (JSON Web Encryption), an entirely separate standard.
Base64URL encoding
Standard Base64 uses +, /, and = padding - characters that require percent-encoding in URLs. Base64URL replaces them: +→-, /→_, and trailing = padding is omitted. This makes tokens safe to embed in HTTP headers, query parameters, and cookies without further escaping.
The header: every field is attacker-controlled
This is the most critical point for a security engineer: the header arrives as part of the token, signed by the token bearer themselves. Before signature verification occurs, the server must parse the header to know which algorithm and key to use. This creates a bootstrapping problem - and most JWT vulnerabilities live exactly here.
alg value to decide which verification function to call, rather than enforcing a pre-configured expected algorithm. An attacker who can change algto none, HS256, or any other value gains control over the entire verification path.Standard payload claims (RFC 7519)
The payload is a JSON object. RFC 7519 defines seven registered claim names, all optional. Applications typically add their own private claims (role, email, tenant_id, etc.). These private claims are the primary target of token forgery attacks.
Servers MUST validate exp - an expired token that passes signature verification should still be rejected. Servers SHOULD validate aud to prevent a valid token for service A being replayed at service B. The jti claim enables replay prevention by tracking consumed token IDs.
Signature computation
The signature covers exactly base64url(header) + "." + base64url(payload) - the "signing input". The signature does not cover any HTTP metadata (headers, path, IP address). If an attacker can modify the header or payload and recompute a valid signature, the server has no way to distinguish the forgery from a legitimate token.
RS256 - Asymmetric signing
For RS256 (RSASSA-PKCS1-v1_5 with SHA-256), the server holds a private key and signs with it. Any party with the public key - often published at /.well-known/jwks.json - can verify. The critical implication: the public key is known to attackers by design, which is the foundation of the algorithm confusion attack.
ES256 - ECDSA signing
ES256 uses P-256 with SHA-256. ECDSA signatures are non-deterministic: the same message signed twice produces different signatures due to a random nonce k. A critical property for the public key recovery attack - two different ECDSA signatures cannot be used for GCD-based recovery (unlike RSA). However, a weak RNG producing repeated k values is catastrophic and has led to private key recovery in real-world cases (the PlayStation 3 ECDSA failure being the canonical example).
The JOSE family of standards
JWT is one specification in the broader JOSE (JSON Object Signing and Encryption) family:
A "JWT" is almost always a JWS with a JSON payload. JWE produces a token with 5 dot-separated segments and is rarely encountered in web application contexts - but when it is, it provides genuine confidentiality of the payload.
Token lifecycle and state
JWTs are stateless by design: the server need not consult a database to validate a token, because the signature is self-contained proof of authenticity. This has a major security implication: there is no built-in revocation mechanism. Once a token is issued, it is valid until its exp claim passes - unless the server maintains a denylist of jti values (negating most of the statelessness benefit) or rotates the signing key (invalidating all outstanding tokens).