Authentication and authorization are where most API security work lives. Get them right and the rest of your defenses operate from a solid foundation. Get them wrong and every endpoint is potentially compromised. This module covers JWT pitfalls, OAuth 2.0 flows for APIs, session management patterns, and the things to test in each.
JWT β the pitfalls
JSON Web Tokens are everywhere. They are also full of footguns:
- “none” algorithm bypass: some libraries accept
{"alg":"none"}and skip signature verification. Older bug; still appears in custom verifiers - Algorithm confusion (RS256 vs HS256): server expects RS256 (asymmetric); attacker submits HS256 token signed with the public key (which they obtained legitimately). HS256 verifier uses the public key as HMAC secret β signature passes
- Weak HMAC secret: JWT signed with
secret123; offline crack via hashcat in seconds - kid injection: kid header pointing to attacker-controlled key
- jku/x5u abuse: JWT claims a key URL; some verifiers fetch and trust it
- Expiration not enforced: token from last year still works
- Token reuse after logout: JWT is stateless; without revocation infrastructure, “logout” just means client deletes token
- Secrets in JWT body: JWT base64-encodes β does not encrypt. Anything in the body is readable
JWT testing checklist
# Test 1: alg=none
echo -n '{"alg":"none","typ":"JWT"}' | base64 -w0
echo -n '{"sub":"admin"}' | base64 -w0
# Final token: HEADER.PAYLOAD. (note trailing dot, empty signature)
# Test 2: HS256 confusion using known RS256 public key
# (Use jwt_tool by ticarpi)
jwt_tool TOKEN -X k -pk public.pem
# Test 3: Crack weak HS256 secret offline
hashcat -a 0 -m 16500 token.txt rockyou.txt
# Test 4: Replay expired token; verify rejection
# Test 5: Decode body β any sensitive fields you can see?
OAuth 2.0 β the flows that matter for APIs
- Authorization Code with PKCE β standard for first-party + native apps. PKCE prevents code interception
- Client Credentials β service-to-service auth; no user involved
- Resource Owner Password Credentials (ROPC) β deprecated; user gives username/password directly to client. Security anti-pattern
- Implicit flow β deprecated; access tokens in URL fragment. Replaced by Auth Code + PKCE
- Device code β for input-constrained devices (TVs, IoT)
Anything still using ROPC or Implicit in 2026 is a finding by itself.
OAuth-specific bugs
- Open redirect in redirect_uri: attacker registers
https://evil.comand tricks user; auth server should validate redirect_uri against pre-registered allow-list - State parameter missing: CSRF on the OAuth callback; state should be unguessable per request
- Authorization code reuse: codes should be single-use; reuse should fail and revoke any tokens issued from that code
- PKCE not enforced: on auth-code flow without PKCE, intercepted code can be exchanged for token
- Refresh token without rotation: long-lived refresh tokens that don’t rotate are persistent compromise risk
- Scope inflation: token grants more scopes than requested
Session management for stateful APIs
Not every API uses JWT. Cookie/session APIs have their own checklist:
Continue reading with Basic tier (βΉ499/month)
You've read 29% of this module. Unlock the remaining deep-dive, quiz, and every other Intermediate module.