Stop Using JWTs

Scope of the debate

  • Most participants distinguish two main use cases:
    • Browser-based user sessions.
    • Service‑to‑service / backend tokens.
  • Broad soft consensus: JWTs are often a poor fit for browser sessions, but can be fine or even ideal for backend and federation scenarios.

JWTs for browser-based sessions

  • Critics say JWTs add complexity over simple opaque session IDs in HttpOnly cookies, with no real benefit if the same server issues and validates them.
  • Main pain points raised:
    • Hard/awkward revocation and logout, especially per-device logout.
    • Replayability and long-lived tokens.
    • Tendency to stuff sensitive or mutable data into tokens, creating cache invalidation and security problems.
  • Several argue: if you already need a datastore (for users, permissions), just store session state there and avoid cryptography for sessions.

Security properties and implementation pitfalls

  • Historical issues: alg=none, algorithm downgrade/confusion, libraries accepting public keys as HMAC secrets, poor defaults.
  • Some argue these were library bugs and are mostly fixed; others say they stem from a spec that encourages footguns and complexity.
  • Disagreement on how “insecure” JWT is today:
    • One camp: “JWT is fine if you constrain algorithms and use good libs.”
    • Other camp: “Spec encourages misuse; CVEs keep appearing; safer designs exist.”

Revocation, “stateless” auth, and logout

  • Core tension: JWTs are marketed as “stateless,” but secure logout and compromise handling require state:
    • Revocation lists / denylists.
    • Per‑user “not valid before” timestamps.
    • Key rotation schemes.
  • Some argue once you add that state, you’ve lost the main advantage over classic sessions.
  • Others counter that revocation lists are much smaller than full session stores and easier to replicate globally.

Cookies, storage, and XSS/CSRF

  • Strong support for HttpOnly, Secure, SameSite cookies for browser sessions.
  • Many caution against storing JWTs in localStorage due to XSS exfiltration; some downplay this if you “don’t allow untrusted JS,” others call that unrealistic.
  • Point that HttpOnly prevents token theft but not XSS-driven misuse.

Alternatives and broader ecosystem

  • Alternatives mentioned: opaque random tokens, signed cookies, PASETO, macaroons, SAML/OIDC patterns, custom schemes.
  • Some praise PASETO/macaroon designs as more misuse-resistant but note limited ecosystem and adoption.
  • Several view the “stop using JWTs” framing as overblown or clickbait; prefer “use JWTs narrowly and carefully.”