State and browser security

Cookies add state

Follow a cookie from Set-Cookie to later Cookie request headers and see how state is layered on top of stateless HTTP exchanges.

HTTP does not automatically connect one request to the next. Each exchange stands alone. Cookies add a small piece of browser-managed state on top of that stateless protocol.

The server sets a cookie in a response:

Set-Cookie: session=abc123; Path=/; HttpOnly; Secure; SameSite=Lax

The browser stores it and sends it on matching later requests:

Cookie: session=abc123

You do not write that Cookie header yourself in frontend code. The browser attaches it based on the URL, path, and domain rules.

Let’s watch it happen with curl. Save cookies to a file on the first request:

curl -c /tmp/cookies.txt -b /tmp/cookies.txt -I https://httpbin.org/cookies/set?session=abc123

The response includes set-cookie: session=abc123. The -c flag writes it to /tmp/cookies.txt. Send a second request with the same file:

curl -c /tmp/cookies.txt -b /tmp/cookies.txt https://httpbin.org/cookies

httpbin returns {"cookies": {"session": "abc123"}}. The cookie traveled with the request, just like a browser would send it.

Path and Domain control where a cookie is sent. Max-Age or Expires make it persistent. Without those, it is normally a session cookie that disappears when you close the browser.

HttpOnly keeps JavaScript from reading it, which limits XSS damage. Secure limits it to HTTPS connections. SameSite restricts when it goes out on cross-site requests.

Cookies ride along automatically on every matching request. Keep them small and scope them tightly. A 4 KB session cookie on every asset request adds up fast.

Be careful with Domain=.example.com. It sends the cookie to every subdomain, including ones you forgot about. I prefer the narrowest domain that still works.

In the browser Network panel, click a request after login and check the Cookies tab. You should see the same name and value the server set, plus flags like HttpOnly and Secure. If a cookie never appears on later requests, compare Path and Domain against the URL you are loading.

Try this on a site you log into: find the session cookie in DevTools, note its flags, and confirm it is not readable from the JavaScript console when HttpOnly is set.

Lesson completed