Cookies and sessions
HTTP is stateless. Each request is complete on its own and the server has no memory of the last one — which is what lets caches and proxies reason about a single request without tracking a conversation, and is also why the web needed a workaround for "remember who I am".
The workaround is a cookie: a value the server asks the browser to store and send back on every later request to that site.
HTTP/1.1 200 OKSet-Cookie: __Host-sid=8f2c...; Secure; HttpOnly; SameSite=Lax; Path=/ GET /account HTTP/1.1Cookie: __Host-sid=8f2c...The cookie is a pointer, not the data
That value is almost always a random identifier and nothing else. The real
session — who you are, what you may do, when you logged in — lives on the server, where it can be revoked.
That indirection is what makes logging out mean something. Put the user's identity into the cookie itself and you cannot take it back: the browser holds it, the server has no list of what it issued, and the only expiry is the one you signed into it.
The attributes are the whole security story
| Attribute | Withholds the cookie from | Attack it addresses |
|---|---|---|
Secure | Any cleartext HTTP request | Network interception |
HttpOnly | document.cookie, i.e. all JavaScript | XSS reading the session |
SameSite=Lax | Cross-site POSTs and subresources | CSRF |
__Host- prefix | Any weaker configuration than host-only, Path=/, Secure | Subdomain injection |
SameSite deserves care, because what it does is narrower than it sounds: the
cross-site request is still sent, and the server still receives and executes it. What
is withheld is only the cookie — so the request arrives unauthenticated and is rejected
on that basis. That is exactly enough to stop CSRF and not one thing more.
Key takeaways
- HTTP is stateless by design; a session is state bolted on by asking the browser to repeat a value.
- The cookie normally holds an opaque id, and the session itself lives server-side — which is what makes revocation possible.
- Secure keeps a cookie off cleartext, HttpOnly keeps scripts away from it, SameSite decides whether other sites’ requests carry it.
- A cross-site request is still sent and still executed. SameSite withholds only the credential, which is exactly enough to defeat CSRF.
- The __Host- prefix forces Secure, host-only and Path=/, because the name is the only part of a cookie the server gets back.