Secure JWT auth with refresh rotation, threat modeling, and the mistakes that get you hacked
Design a production JWT auth flow with access/refresh rotation, token family revocation, and a concrete threat model — including the 6 common JWT mistakes that lead to breaches and how to avoid each one.
You are a security engineer who has seen JWT implementations get breached. Design and implement a production-grade JWT auth flow for [STACK] that defends against real attacks, not just textbook ones. Threat models to explicitly address (for each, state the attack AND your defense): 1. Token theft via XSS — attacker injects script, steals token from JS-accessible storage. 2. CSRF on the refresh endpoint — attacker triggers a refresh from a malicious site. 3. Replay attacks — attacker captures and reuses a valid token. 4. Token sidejacking — attacker intercepts token over a compromised network. 5. Refresh token theft — attacker steals a long-lived refresh token and uses it days later. Implementation requirements: - Short-lived access token (10–15 min) + refresh token with ROTATION (every refresh issues a new refresh token and invalidates the old one). - Refresh token family tracking: store a `family_id` and `jti` server-side. If a revoked refresh token is reused, invalidate the ENTIRE family (this catches token theft after rotation). - Token blacklist strategy: explain when to use a blacklist vs short expiry. If using a blacklist, specify the storage (Redis with TTL = token remaining lifetime, not a growing database table). - Client storage recommendation with explicit reasoning: * Access token: in-memory variable (NOT localStorage, NOT sessionStorage) — survives only the tab session, invisible to XSS. * Refresh token: httpOnly + Secure + SameSite=Strict cookie — inaccessible to JS, CSRF-protected. * Explain WHY this split exists. - Sign with RS256 or ES256 (asymmetric) for microservices, HS256 only for monoliths. Justify the choice. - Validate ALL claims: exp, iat, aud, iss, sub. Reject tokens with 'none' algorithm. ❌ WHAT NOT TO DO (include this section — these are the mistakes that cause breaches): 1. Storing JWTs in localStorage (XSS = game over). 2. Not validating the `aud` claim (allows tokens minted for Service A to be used on Service B). 3. Using a symmetric secret that's the same across all environments. 4. Setting refresh token expiry to 30+ days with no rotation. 5. Trusting the `alg` header from the token itself (algorithm confusion attack). 6. Not revoking all tokens on password change. Provide: - Full implementation: login, refresh, logout (revoke family), verify middleware. - TypeScript types for token payloads and stored refresh records. - Environment variables / secrets needed. - A summary table: Attack → Defense → Implementation Detail. Return the implementation first, then the threat model table, then the 'What Not To Do' section.
- Source
- promptfork seed
- License
- CC-BY-4.0
- Published
- 6/23/2026