JWT Structure and Signature Attack Lab (Interactive)
Edit claims in a live token, then try alg:none and RSA-to-HMAC confusion. Decode, tamper, and re-verify a real base64url JWT against a verifier whose algorithm whitelist you control, replaying CVE-2015-9235 and CVE-2016-5431.
JWT Anatomy & Signature Attack Lab
Forge tokens against three classic exploits, then harden the verifier's algorithm whitelist to kill them.
{"alg":"RS256","typ":"JWT","kid":"auth-key-2026-v1"}{"sub":"usr_98124","role":"user","iss":"https://auth.company.com","exp":1774889200}Signature recomputed from header.payload matches — claims trusted.
Attack scenario
JWS ≠ encryption. Every byte above is public base64url — never put raw passwords or PII in claims (use JWE if confidentiality is required).
Defenses to state in interviews: whitelist algorithms, pin iss/aud, pick kid from JWKS only for the expected alg, prefer ES256/Ed25519 over RS256 for smaller keys at equal strength.
Signature here is a deterministic demo digest standing in for real RSA/HMAC math.
How It Works Under the Hood
A JWT is just three base64url segments, header, payload, and signature, joined by dots; nothing inside is encrypted, so an attacker can decode and edit any claim. Integrity depends entirely on signature verification, and history shows libraries get it wrong. Trusting the token header's alg field permits the alg:none attack (CVE-2015-9235) that drops the signature, and accepting an attacker-chosen HMAC key enables RSA-to-HMAC key confusion (CVE-2016-5431), where the public key becomes the symmetric secret. The safe pattern is pinning an explicit algorithms whitelist server-side. This lab lets you forge the token and flip the verifier's behavior to see both outcomes.
Core Architectural Principles
- Payload edits re-encode with real base64url, then fail signature checks unless the attack bypasses them.
- alg:none succeeds only when the verifier trusts the attacker-supplied header algorithm field.
- Key-confusion forgeries are defeated by pinning the library algorithms option to RS256 explicitly.
Say JWT out loud as JSON Web Token and describe the three segments before attacking them. Explain alg:none and the RS256-to-HS256 confusion with their CVE numbers, then land the design answer: pin the verifier algorithm list, keep tokens short-lived, never put secrets in payload claims, and use JWKS rotation instead of embedding public keys.
Self-contained tokens are unverifiable-in-reverse and fragile to library behavior; the mitigation is strict verifier configuration.