PromptFork

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.

Open in Studio
Prompt
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

More prompts you might like

Next.js 15 App Router page with streaming, caching, and server data

Scaffold a production App Router page: Server Component data fetching, Suspense streaming for instant TTFB, correct cache strategy (fetch cache vs unstable_cache vs revalidatePath), loading/error boundaries, and generateMetadata — with the non-obvious patterns most tutorials skip.

New

Tailwind analytics dashboard with animated stat cards, dark mode, and skeleton loading

Production-grade dashboard layout: KPI cards with counting animations and trend sparklines, a chart area, activity table — all with dark mode, skeleton loading states, and responsive breakpoints defined to the pixel.

New

Supabase RLS: owner-write, public-read policies for a table

Generate correct, non-recursive RLS policies so anyone reads published rows and only owners edit their own.

New

Stripe webhook handler with signature verify + idempotency

Production-ready Stripe webhook route that verifies the signature and processes events exactly once.

New

.cursorrules for a strict TypeScript + React codebase

A tuned .cursorrules file that keeps Cursor's agent on-convention: strict types, no dead code, match existing patterns.

New

Refactor a React component into clean custom hooks

Extract stateful logic from a bloated component into typed, testable custom hooks.

New