| name | design-session-management |
| description | Use when implementing user authentication state — creating, storing, transmitting, and expiring session tokens or cookies in a web application. |
| source | OWASP Session Management Cheat Sheet (owasp.org/www-project-cheat-sheets); OWASP Top 10 2021 A07; CWE-613; NIST SP 800-63B |
| tags | ["security","owasp","sessions","cookies","authentication","web","developer"] |
Design Session Management
Issue cryptographically random session tokens, transmit them exclusively over HTTPS with HttpOnly/Secure/SameSite cookie attributes, and enforce idle and absolute timeouts — eliminating fixation, hijacking, and token prediction attacks.
Why This Is Best Practice
Adopted by: Codified in OWASP Top 10 2021 A07 (Identification and Authentication Failures) and NIST SP 800-63B (Digital Identity Guidelines). Django, Rails, Laravel, Spring Session, and ASP.NET Core all implement these defaults. PCI DSS v4.0 Requirement 8.2 mandates session controls. NIST 800-63B is the authoritative federal standard for session management in US government applications.
Impact: Session hijacking is among the most common post-authentication attack vectors — Verizon DBIR 2023 identifies stolen session tokens as a top initial access technique in web application breaches. Proper session invalidation on logout prevents 100% of fixation attacks. HttpOnly cookies prevent JavaScript from reading session tokens even when XSS occurs, limiting the blast radius.
Why best: JWTs stored in localStorage are the common alternative — they lack server-side revocation, persist after logout, and are readable by XSS. Server-side sessions with HttpOnly cookies give developers full control over validity and are immune to JavaScript-based theft.
Sources: OWASP Session Management Cheat Sheet; NIST SP 800-63B; Verizon DBIR 2023; CWE-613
Steps
-
Generate cryptographically random session IDs — at least 128 bits of entropy from a CSPRNG. Never use sequential IDs, timestamps, or user-derived values.
import secrets
session_id = secrets.token_urlsafe(32)
SecureRandom sr = new SecureRandom();
byte[] token = new byte[32];
sr.nextBytes(token);
String sessionId = Base64.getUrlEncoder().withoutPadding().encodeToString(token);
-
Set all four protective cookie attributes:
Set-Cookie: session=<token>; HttpOnly; Secure; SameSite=Lax; Path=/
HttpOnly — JavaScript cannot read the cookie (blocks XSS-based token theft)
Secure — cookie only sent over HTTPS
SameSite=Lax — blocks CSRF from cross-site form POST (see prevent-csrf)
Path=/ — restrict to your app path, not subpaths of shared hosts
-
Rotate session ID on privilege escalation — generate a NEW session ID after login, role changes, or permission grants to prevent session fixation:
old_data = session.get_data()
session.invalidate()
new_session = session.create_new()
new_session.set_data(old_data)
new_session.set('user_id', authenticated_user.id)
-
Enforce idle and absolute timeouts:
IDLE_TIMEOUT = 30 * 60
ABSOLUTE_TIMEOUT = *
last_activity = session[]
created_at = session[]
time.time() - last_activity > IDLE_TIMEOUT:
session.invalidate()
time.time() - created_at > ABSOLUTE_TIMEOUT:
session.invalidate()
Rules
- Never store session IDs in URLs (
?sessionid=...) — they appear in logs, referrer headers, and browser history.
- Session tokens must not contain user data (user ID, role) — store a random ID that maps server-side to user state.
- Concurrent session control (invalidate old sessions on new login) prevents credential-sharing; implement where security requirements demand it.
- Session fixation: always rotate ID on login; never accept a session ID set by the client pre-login.
Common Mistakes
- Using userID + timestamp as session token — predictable, brute-forceable.
- Deleting the cookie but not the server-side session on logout — the token remains valid if captured.
- Setting long absolute timeouts for convenience — 30-day sessions mean a stolen token is valid for 30 days.
- HttpOnly cookies + JWT in localStorage — mixing models: choose one. HttpOnly cookies handle both transport and XSS protection.