InterviewHubPRO
Section Overview
Q26

Question 26 of 50

Part 3: Authentication, Authorization & Cryptographic Standards (26 - 35)

52%
Web Security & OWASP (50 Qs)•Part 3: Authentication, Authorization & Cryptographic Standards (26 - 35)

JSON Web Token (JWT) Security & Pitfalls: Algorithm confusion (alg: none), RS256 vs. HS256, and revocation.

JWT Internal Structure & Common Attacks

A JSON Web Token consists of three base64url-encoded parts separated by periods: Header.Payload.Signature. Because JWTs are stateless by design, common implementation flaws create devastating vulnerabilities.

lua
+-----------------------+     +-----------------------+     +-----------------------+
|        HEADER         |  .  |        PAYLOAD        |  .  |       SIGNATURE       |
| {"alg": "RS256", ...} |     | {"sub": "123", ...}   |     | HMAC / RSA signature  |
+-----------------------+     +-----------------------+     +-----------------------+

1. The alg: "none" Vulnerability

Early JWT libraries allowed the header to declare {"alg": "none"}. Attackers stripped the signature and sent arbitrary payloads (e.g. {"role": "admin"}), which poorly implemented validators accepted without error. Mitigation: Always explicitly whitelist the acceptable algorithm on the server:

typescript
jwt.verify(token, publicKey, { algorithms: ['RS256'] }); // Never allow 'none' or HS256!

2. Algorithm Confusion Attack (RS256 vs. HS256)

If a server expects RS256 (asymmetric; verifies with public key), an attacker can sign a forged token using HS256 (symmetric HMAC) using the server’s public key as the HMAC secret! If the backend blindly trusts the header algorithm, verification succeeds because the attacker used a known public key as the symmetric secret.

3. Real-Time Token Revocation (The JTI Bloom Filter Pattern)

Because JWTs cannot be revoked without maintaining server-side state, modern architectures include a unique token ID (jti) in the payload. When a user logs out or changes passwords, the jti is pushed to a Redis Bloom Filter or TTL set until its natural expiration. Validating the jti against Redis takes $< 1$ millisecond.