JSON Web Tokens (JWT) have become the default authentication token format in modern APIs. They’re compact, stateless, and when implemented correctly, secure. When implemented poorly, they’re a source of authentication bypass and privilege escalation. This module covers JWT structure, common attacks, and the concrete defences.
JWT structure
header.payload.signature
# Base64-decoded example:
Header: {"alg":"HS256","typ":"JWT"}
Payload: {"sub":"priya","role":"admin","exp":1700000000}
Signature: HMAC-SHA256(header + "." + payload, SECRET)
Signature is what makes JWT tamper-evident. Change the payload, signature no longer matches, verifier rejects.
Attack 1: alg=none
JWT spec includes an “alg” header field. One value: none β meaning no signature. Historical JWT libraries accepted alg:none at verification β trusting the header without actually checking the signature.
# Modified JWT with alg=none:
eyJhbGciOiJub25lIn0.eyJzdWIiOiJhZG1pbiJ9.
# (empty signature, decoded header says alg=none)
# Vulnerable verifier: signature check skipped because alg=none
# Attacker is now admin
Defence: explicitly reject alg: none. Whitelist allowed algorithms. Most modern libraries fixed this but legacy code still appears.
Continue reading with Pro tier (βΉ4,999/year)
You've read 25% of this module. Unlock the remaining deep-dive, quiz, and every other Advanced/Expert module.