VibeSecurity

Comparison

JWT vs session cookies: security differences explained

A server-side session stores login state on the server and gives the browser a random id. A JWT puts signed claims in the token itself so the server does not need to look anything up. Generated apps often use one without the author knowing which. This page explains the security trade-offs.

By the VibeSecurity team4 min read

First, a common confusion

JWT and cookie are not opposites. A JWT is a token format. A cookie is a way to store and send a value. You can put a JWT in a cookie, and you can put a random session id in a header. The real comparison is between stateless signed tokens and server-side session state.

The differences side by side

AspectJWT (stateless token)Server-side session
What the browser holdsSigned claims such as the user id and expiry. RFC 7519 defines the format.A random identifier with no meaning on its own. OWASP asks for at least 64 bits of entropy.
Where the truth livesIn the token. The server checks the signature and the claims.In a server-side store such as a database or cache.
Logging out and revokingThe token remains valid until exp unless you keep a deny list or use short lifetimes with a revocable refresh token.Delete the record on the server and the id stops working. OWASP says logout must invalidate the session server-side.
Can the user read the contentsYes for a signed token. The payload is encoded, not encrypted, so keep secrets out of it.No. The id reveals nothing.
Typical implementation mistakesTrusting the algorithm named in the token header, skipping issuer and audience checks and weak signing secrets, which RFC 8725 covers. Very long lifetimes add to the damage.Predictable ids, not renewing the id after login, missing cookie attributes, sessions that never expire.
CSRF exposureDepends on transport. In a cookie, CSRF defences are needed. In an Authorization header, the browser does not attach it automatically.Normally a cookie, so CSRF defences are needed. OWASP describes SameSite as defence in depth, not a replacement for CSRF tokens.
XSS exposureDepends on storage. In localStorage, injected script can read it. In an HttpOnly cookie it cannot.In an HttpOnly cookie, injected script cannot read the id.

What JWTs leave to you

  • Choosing and enforcing the algorithm on the server. RFC 8725 says libraries must let the caller specify accepted algorithms and must not trust the header alone.
  • Validating issuer, audience and expiry on every request.
  • A revocation story: short access token lifetimes, a refresh token you can revoke, or a deny list for emergencies.
  • Keeping personal data and secrets out of the payload.
  • Protecting the signing key, and rotating it if it may have leaked.

What server-side sessions leave to you

  • A session store that every server instance can reach.
  • Setting Secure, HttpOnly and SameSite on the cookie.
  • Renewing the session id after login and after any privilege change, which OWASP requires to prevent fixation.
  • Idle and absolute timeouts, enforced on the server.
  • CSRF protection for state-changing requests.

What to check whichever you pick

  • The token or session id is not stored in localStorage or sessionStorage.
  • The cookie has Secure, HttpOnly and SameSite set.
  • After logout, replaying the old token or id against an API route is rejected, or expires within minutes.
  • Changing one character of a JWT makes the server reject it.
  • A JWT with the algorithm set to none, or signed with a different algorithm, is rejected.
  • State-changing requests have CSRF protection when auth travels in a cookie.
  • Expiry is enforced on the server, not only in client code.

Frequently asked questions

Is JWT more secure than session cookies?

No, and not less either. They move state to different places. Sessions are simpler to revoke. JWTs avoid a lookup but need careful validation and a plan for revocation. Most weaknesses come from storage and validation mistakes, not the format.

Can I store a JWT in a cookie?

Yes. A JWT in a Secure, HttpOnly, SameSite cookie is a common design. It removes the token from JavaScript's reach, and it means you need CSRF defences because the browser attaches the cookie automatically.

How do I log a user out if I use JWTs?

A stateless token stays valid until it expires. Use short-lived access tokens with a refresh token you can revoke on the server, or keep a deny list of revoked token ids for the rare cases where you must cut access at once.

Are JWTs encrypted?

Not usually. A signed JWT is encoded so anyone holding it can read the payload. The signature stops tampering, not reading. RFC 7519 also defines encrypted JWTs, which most web apps do not use.

Sources

  1. 1.RFC 7519: JSON Web Token (JWT)
  2. 2.RFC 8725: JSON Web Token Best Current Practices
  3. 3.OWASP Session Management Cheat Sheet
  4. 4.OWASP Cross-Site Request Forgery Prevention Cheat Sheet
  5. 5.MDN: Set-Cookie header
  6. 6.MDN: Using HTTP cookies