Stop using JSON Web Tokens for user sessions

Developers are debating whether JSON Web Tokens (JWTs) are appropriate for managing user sessions in web apps, especially single-page applications. Many argue that JWTs themselves aren’t the problem; the real risks come from storing them in JavaScript-accessible places like localStorage, weak XSS protection, and the difficulty of token revocation, leading some to prefer traditional server-side sessions or JWTs stored in HttpOnly, SameSite cookies. Others note that JWTs still make sense in distributed systems and APIs, but stress that they must be used with clear threat models, short lifetimes, and careful implementation to avoid common security pitfalls.

Scope of the Debate

  • Many argue the article is really about XSS and storage choices, not JWTs themselves.
  • Repeated clarification: JWT is just a token format; it can be used with cookies or other storage, and isn’t inherently opposed to “cookie-based sessions.”

Where to Store Session State

  • Strong camp: store session identifiers/JWTs in HttpOnly, Secure, SameSite cookies.
    • Protects against direct token theft by XSS.
    • Avoids manual header plumbing; browser sends cookies automatically.
  • Criticism of localStorage / JS-accessible storage:
    • Easily exfiltrated by XSS; especially problematic for long-lived refresh tokens.
    • Some frameworks (Firebase, Cognito) default to local/IndexedDB and cannot use HttpOnly.
  • Minority view: localStorage is “fine” because XSS means “game over” anyway, and attackers can still abuse cookies via in-browser requests.

CSRF, SameSite and Cookies

  • Recommendation: set SameSite on sensitive cookies.
    • Lax often seen as enough for CSRF protection; Strict can break first-page logged-in behavior.
  • Some confusion over how cross-site form posts interact with cookies; SameSite is pointed to as the control.

XSS Threat Model

  • One side: if JS can be injected, the attacker can already act as the user (issue requests), so cookie vs localStorage matters little.
  • Other side: HttpOnly still meaningfully limits damage by preventing token exfiltration and reuse from another device; layered defenses matter.

JWT Design and Revocation

  • JWT advantages cited:
    • Stateless validation; good for APIs, distributed systems, and microservices.
    • Downstream services can authorize via JWT without hitting an auth DB each time.
  • Major drawback: hard to revoke / log out:
    • Typical pattern: short-lived access tokens + long-lived refresh tokens, often with refresh tokens opaque and DB-checked.
    • Once you add revocation lists or DB checks, you lose some “stateless” benefits; some question why use JWT at that point.
  • Several recommend simple opaque session IDs in cookies, converting to JWTs only internally at gateways.

Legal / UX / Practical Concerns

  • Clarification that functional/session cookies usually don’t require consent banners; confusion around “cookie directive.”
  • Some complain about absolutist security guidance (e.g., very short timeouts) harming usability.
  • Others criticize “Stop using X” articles that don’t offer clear, practical alternatives or nuance.