Session Management &Secure Cookies
HttpOnly (blocks JavaScript from reading the cookie, defeating XSS theft), Secure (sends it only over HTTPS), and SameSite (limits cross-site sending, defeating most CSRF). Also use long random session IDs, regenerate them on login, and expire them server-side.HTTP is stateless: every request is independent. Session management is the layer that ties requests together so a user stays logged in. Get it wrong and attackers can steal sessions, ride existing ones, or hijack accounts. This guide covers how sessions work, the cookie flags that protect them, and the common attacks. If you are deciding between server sessions and tokens, start with JWT vs Session Tokens.
What Is Session Management?
When a user logs in, the server creates a session: a record of who they are: and gives the browser a session ID. The browser sends that ID back on every subsequent request, usually in a cookie, so the server knows which session the request belongs to. The session ID is effectively a temporary password: anyone who holds it is treated as the logged-in user, which is why protecting it is critical.
How Do Session Cookies Work?
The server issues the cookie with a Set-Cookie response header, and the browser returns it automatically on matching requests. The security of the whole scheme depends on the flags you attach:
Set-Cookie: sid=9f3a...e7; HttpOnly; Secure; SameSite=Lax;
Path=/; Max-Age=3600
What Are the Secure Cookie Flags?
| Flag | What It Does | Attack It Prevents |
|---|---|---|
| HttpOnly | Blocks JavaScript from reading the cookie via document.cookie | Session theft through XSS |
| Secure | Sends the cookie only over HTTPS connections | Interception over plain HTTP |
| SameSite=Lax / Strict | Limits or blocks the cookie on cross-site requests | Cross-site request forgery (CSRF) |
| Path / Domain | Scopes the cookie to specific paths or hosts | Over-broad cookie exposure |
| Max-Age / Expires | Sets how long the cookie lives | Indefinite session lifetime |
HttpOnly is the one that connects session security to XSS. Even if an attacker achieves script execution, an HttpOnly cookie cannot be read from JavaScript, which blocks the most common XSS payload: stealing the session cookie. See our XSS guide for how that attack works.
What Are the Main Session Attacks?
- Session hijacking: the attacker steals a valid session ID (via XSS, network sniffing, or malware) and uses it to impersonate the user. Defenses: HttpOnly, Secure, short lifetimes, and binding sessions to context.
- Session fixation: the attacker sets a known session ID before the victim logs in, then reuses it afterward. Defense: regenerate the session ID on every login and privilege change.
- Cross-site request forgery (CSRF): the attacker tricks the browser into sending the session cookie on a forged request. Defense: SameSite cookies and CSRF tokens. See our CSRF guide.
- Predictable session IDs: short or sequential IDs can be guessed. Defense: long, cryptographically random identifiers.
How Do You Secure Session Management?
- Generate session IDs with a CSPRNG; make them at least 128 bits of entropy
- Set
HttpOnly,Secure, andSameSiteon every session cookie - Regenerate the session ID on login and on privilege escalation to prevent fixation
- Expire sessions both by idle timeout and by absolute maximum lifetime
- Invalidate the session server-side on logout: do not just delete the cookie
- Store sessions server-side (or use signed, encrypted tokens) and never trust client-supplied session data
- Serve the entire site over HTTPS and enable HSTS
- Re-authenticate before sensitive actions such as changing email or password
Sessions vs JWTs: Which Should You Use?
Server-side sessions are easy to revoke instantly and keep state on the server. JWTs are stateless and scale well across services but are harder to revoke before expiry. Many teams use both: short-lived JWT access tokens with server-side refresh tokens. We cover the full trade-off, including storage and revocation, in JWT vs Session Tokens: Which Is More Secure?