← Computer Networks
Sessions, Auth & Browser Security

Cookies & Sessions

Watch: "HTTP Cookies Crash Course" — Hussein Nasser

HTTP is stateless, so cookies and server-side sessions are the classic mechanism for remembering who a client is across requests. Their attributes are also one of the highest-leverage areas for web security interview questions, since a misconfigured cookie is a direct path to session hijacking or CSRF.

What Is a Cookie?

A cookie is a small piece of text a website asks your browser to store, then hands back to that same site on every later visit. Sites use this to remember things about you between page loads — since a web server normally forgets you the instant it finishes answering one request, the cookie is what lets it recognize you again a minute, or a month, later.

What Is a Session?

A session is the actual record of who you are and what you're doing, kept on the server, not in the cookie itself. The cookie just carries a short ID number pointing at that record — so if someone steals the cookie, they get a pointer to your session, not your password or personal details directly.

Where This Is Used

A Day-to-Day Example

Think of checking into a hotel. At the front desk you hand over ID once, and in return you get a room key card with no name or account number printed on it — just a code. Every door in the building reads that code and looks up, in the hotel's own system, who you are and what you're allowed to access. Lose the card and a stranger can open your door, but they still can't see your actual identity just from holding it — the hotel's internal records are what matter.

Deep Dive: The Login-to-Session Flow, On the Wire

Login then cookie-authenticated requestsBrowserapp.example.comPOST /login {email, password}200 + Set-Cookie: session_id=…HttpOnly, Secure, SameSitebrowser stores the cookieGET /dashboard, Cookie: session_id=…sent automatically200 dashboardserver looks up the session
The server creates a session after checking the password and hands the browser only a random ID in a cookie. From then on the browser attaches the cookie to every request to that site, and the server maps the ID back to the user. The raw messages are below.
browserserver
POST /login HTTP/1.1
Host: app.example.com
Content-Type: application/json

{"email":"[email protected]","password":"••••••••"}

HTTP/1.1 200 OK
Set-Cookie: session_id=8f3ac1b2e9; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=604800

--- every subsequent request from this browser to app.example.com ---

GET /dashboard HTTP/1.1
Host: app.example.com
Cookie: session_id=8f3ac1b2e9

The server never trusts anything about the client's identity beyond that opaque session_id. On every request it looks the ID up in a session store (in-memory, Redis, or a database) to find the actual user record, role, and any other session state. The cookie itself carries no meaningful data — that's the point: if it's stolen, an attacker gets a session ID they can replay, not the user's password or any directly readable identity claim.

Deep Dive: Cookie Attributes and What Each One Actually Stops

Key Pointers

How It Works

  1. The user authenticates; the server creates a session record (or signs a token) representing that identity.
  2. The server responds with Set-Cookie carrying the session ID (or token), with HttpOnly/Secure/SameSite set appropriately.
  3. The browser stores the cookie and automatically includes it in the Cookie header on future requests to the matching origin.
  4. On each request, the server looks up the session ID in its store (or verifies the token's signature) to authenticate the request.
  5. The session ends via Max-Age/Expires or explicit server-side invalidation — logout deletes the session record.

Try It Yourself

# Capture the Set-Cookie header from a login response
curl -v -X POST https://app.example.com/login \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","password":"secret"}' \
  -c cookies.txt

# Reuse the saved cookie jar on a follow-up authenticated request
curl -v -b cookies.txt https://app.example.com/dashboard

# In Chrome DevTools: Application tab → Storage → Cookies → pick the domain
# shows every cookie's Name, Value, Domain, Path, Expires, HttpOnly, Secure, SameSite

# Try to read a cookie from the console to confirm HttpOnly is working
# (run in DevTools Console on the target site)
document.cookie   // HttpOnly cookies will NOT appear in this output

Interview Q&A

Q: Why store just a session ID in the cookie instead of the user's actual data?

A: It minimizes the blast radius of a stolen cookie and keeps the cookie small (there's a practical ~4KB cap per cookie). If the ID alone leaks, an attacker gets a replayable session, not directly readable user data — and because the real state lives server-side, you can revoke it instantly by deleting the session record, which you can't do with data embedded directly in a client-held token.

Q: How does SameSite=Lax mitigate CSRF, specifically?

A: CSRF works by getting a victim's browser to fire a request to a site they're authenticated on, from a page they didn't intend to interact with that site — e.g. an <img src="https://bank.example.com/transfer?to=attacker&amount=1000"> embedded on a malicious page. With SameSite=Lax, the browser won't attach the session cookie to that background cross-site request at all, so the request arrives unauthenticated and the server rejects it. It still allows the cookie on top-level navigation (a user clicking a normal link into your site), which is what makes Lax the practical default instead of Strict.

Q: What's the trade-off between server-side sessions and stateless tokens for scaling?

A: Server-side sessions are trivially revocable — delete the record and the user is logged out everywhere immediately — but every request needs a lookup against a shared store, which becomes a scaling and availability dependency once you have more than one server instance. Stateless tokens (like a JWT) remove that lookup — any instance can verify the signature locally — but revocation before natural expiry is hard; you either accept it can't happen instantly, or you reintroduce state via a denylist, which gives back some of the scaling benefit you were trying to gain.

Q: If HttpOnly stops JavaScript from reading the cookie, does that mean XSS is no longer a risk for a site using cookie-based auth?

A: No — it stops one specific attack (exfiltrating the raw session token), not XSS itself. An attacker with script execution on your page can still make authenticated requests on the victim's behalf using the browser's ambient cookie — they just can't steal the cookie value to replay it elsewhere later. HttpOnly narrows the damage; it doesn't neutralize XSS as a threat.

System Design Tie-in

Cookie/session design comes up directly whenever you're asked to design authentication for a web app, and it's one of the few areas where interviewers expect exact header names, not just concepts. For a multi-instance backend, be ready to say you'd back sessions with Redis (shared, fast, supports TTL-based expiry natively) rather than in-process memory, since in-process sessions break the moment a load balancer routes a user's next request to a different instance. For a system spanning multiple subdomains (app.example.com, api.example.com), the Domain attribute decision matters — setting Domain=.example.com shares the cookie across subdomains but also widens the blast radius if any one subdomain is compromised. For a public API consumed by third-party clients (mobile apps, other backends) rather than a browser-hosted frontend, token-based auth in an Authorization header is usually preferred over cookies, since cookies are a browser-specific mechanism.

Trade-offs

Server-side sessions are trivially revocable — delete the record and the user is logged out everywhere instantly — but require a shared, stateful store and a lookup on every request. Stateless cookie-stored tokens scale without that shared store but are hard to revoke before they expire and put more of the security burden on the token itself. The interview pitfall to watch for: forgetting SameSite/CSRF protection on cookie-based auth, since browsers attach cookies automatically even to cross-site requests unless SameSite restricts it — that gap is exactly what CSRF exploits.