Intermediate

Cookies, session tokens, and web sessions

Design web sessions with secure cookies, server-side or stateless session tokens, timeouts, and protection against fixation and CSRF.

After a user signs in, a web application needs to remember them on every request. That is the job of the session, usually carried by a cookie. Session design determines how long access lasts, how it ends, and how exposed it is to theft.

Kinds of session state

KindWhat the cookie holdsAdvantagesDrawbacks
Server-side sessionA random session identifier; data lives in a server store.Immediate revocation; small cookie; data hidden from the client.Requires a shared store across instances.
Stateless (client-side) sessionSigned and usually encrypted session data, for example a JWT or encrypted blob.No server store; scales easily.Hard to revoke before expiry; larger cookies; key management.

Server-side sessions are the safer default. Stateless sessions need short lifetimes and a revocation strategy, as with self-contained tokens.

AttributeRecommendationWhy
SecureAlways.Sent only over HTTPS.
HttpOnlyAlways for session cookies.Not readable by JavaScript, limiting XSS theft.
SameSiteLax or Strict; None only when cross-site use is required (and then Secure is mandatory).Limits cross-site sending and CSRF.
DomainOmit.Host-only cookies are not sent to sibling subdomains.
Path/Paths are not a security boundary.
Max-Age / ExpiresOmit for a browser-session cookie; set for “remember me”.Controls persistence on the device.
__Host- prefixUse for session cookies.Browser enforces Secure, Path=/, and no Domain.
Set-Cookie: __Host-session=Xk3f9…; Secure; HttpOnly; SameSite=Lax; Path=/

Session lifecycle

  • Generate identifiers with a cryptographically secure random generator and at least 64 bits of entropy.
  • Regenerate the session identifier at login and at privilege changes to prevent session fixation.
  • Idle timeout: end sessions after inactivity, shorter for sensitive applications.
  • Absolute timeout: end sessions after a maximum lifetime regardless of activity.
  • Re-authenticate for sensitive actions, such as changing email or payment details.
  • Logout invalidates the session server-side, clears the cookie, and, where relevant, ends the identity provider session.
  • Show active sessions to users and let them revoke them.

CSRF

Browsers attach cookies automatically, so another site can trigger requests with the user’s session. Defenses:

  1. SameSite=Lax or Strict on session cookies.
  2. Anti-CSRF tokens (synchronizer or double-submit) for state-changing requests.
  3. For JSON APIs, require a custom header that forces a CORS preflight.
  4. Never change state with GET.

Where should a browser keep tokens?

StorageXSS can read it?CSRF risk?Notes
HttpOnly cookieNoYes, mitigateBest for session identifiers; used by the BFF pattern.
JavaScript memoryYes, while the page runsNoLost on reload; good for short-lived access tokens.
sessionStorage / localStorageYes, persistentlyNoAvoid for tokens; any XSS can exfiltrate them.

Sessions in a federated world

A user signed in through SSO has at least two sessions: one at the identity provider and one at each application. Their lifetimes are independent. Ending the application session does not end the identity provider session, and vice versa, unless logout is propagated. See OpenID Connect in depth and sessions, tokens, and revocation.

Browsers increasingly block third-party cookies. Patterns that rely on cookies inside cross-site iframes, such as silent token renewal and front-channel logout, become unreliable. Prefer same-site architectures and back-channel mechanisms.

Session cookies versus access tokens

Session cookieAccess token
AudienceThe application that set it.A resource server (API).
Sent byThe browser, automatically.The client, explicitly.
Typical lifetimeMinutes to days, with idle timeout.Minutes.
ThreatsCSRF, theft via malware.Leakage, replay, XSS when held by JavaScript.

References

Knowledge is better when it is shared.Improve this page

Type to search the entire handbook.