awesome-everything RU
↑ Back to the climb

Security

JWT pitfalls: break and harden an auth flow

Crux Hands-on project — build a JWT auth flow, attack it with alg:none, algorithm confusion, and kid injection, then harden it and prove each exploit is closed.
Your altitude — climbing toward senior
ZeroJuniorMiddleSenior
You are at senior altitude — in orbit
◷ 200 min

Reading about JWT attacks is not the same as landing one. Build a small auth flow, forge tokens against it — alg:none, RS256-to-HS256 confusion, a missing aud check, an attacker kid — then apply the unit’s defenses and prove with a failing exploit that each hole is closed.

Goal

Turn the unit’s mental model into a reproducible security loop: build a verifier, attack it the way a pentester would, harden it by pinning the algorithm and validating claims, and verify each fix with an exploit that now fails.

Project
0 of 7
Objective

Build a JWT-protected API with login, an authenticated /admin route, and refresh, then run an attack suite (alg:none, algorithm confusion, missing aud, attacker kid) — first proving each exploit succeeds against the naive version, then proving it fails after hardening.

Requirements
Acceptance criteria
  • A before/after table for the four exploits: each one reaches /admin (or refresh) against the naive verifier and is rejected with a clear error against the hardened verifier — shown by actual request/response output, not described.
  • The hardened verifier rejects a wrong-aud token even when its signature is valid, and rejects an attacker-kid token without ever fetching from the header-named URL.
  • Replaying a rotated refresh token triggers family revocation: the legitimate session's next refresh also fails, proving reuse detection fired (demonstrated against the running service).
  • A one-paragraph write-up mapping each defense (algorithm pin, key binding, claim checks, kid allowlist, rotation, storage) to the specific exploit it closes and the RFC 8725 guidance behind it.
Senior stretch
  • Add a revocation list (or short-lived deny-cache keyed on jti) so a confirmed-compromised access token can be killed before exp, and measure the per-request overhead it adds.
  • Add a brute-force demo: configure an HS256 path with a weak human-chosen secret, crack it offline from a captured token, then show a 256-bit CSPRNG secret makes the same attack infeasible.
  • Wire CSRF defenses for the cookie-stored refresh token (SameSite plus a CSRF token on the refresh endpoint) and prove a cross-site refresh request is rejected.
  • Run the attack suite in CI as a security regression gate: the build fails if any forged token ever reaches a protected route.
Recap

This is the loop you will run on every real auth review: build the flow, attack it the way an adversary would, then harden by never trusting the token to describe its own verification — pin the algorithm, bind and allowlist keys, validate exp/nbf/iss/aud, resolve kid server-side, and contain leaks with short TTLs, refresh rotation, and XSS-aware storage. Landing each exploit once and watching it fail after the fix turns RFC 8725 from a checklist into instinct.

Continue the climb ↑CSRF in the SameSite era: why the default helped but didn''''t kill it
shortcuts expand
search
K
prev piece
k
next piece
j
cycle tier
t
this menu
?
sources2
expand
  1. 01
  2. 02

Trademarks belong to their respective owners. Editorial reference only.