What is Cookies?
Small name-value pairs a server asks the browser to store and send back on matching requests, used for sessions, preferences, and tracking.
Definition
An HTTP cookie is set by a Set-Cookie response header (or by JavaScript via document.cookie) and stored by the browser. On later requests to a matching domain and path, the browser automatically adds it in a Cookie header. That automatic behavior is what makes cookies the standard way to keep a user signed in across stateless HTTP requests, usually by storing an opaque session ID that the server maps to session data. The current standard is RFC 6265; its revision, RFC 6265bis, is still an IETF draft but already describes behavior browsers ship, including SameSite. Attributes control scope, lifetime, and security. Domain and Path set where the cookie is sent; Expires or Max-Age make it persistent, otherwise it is a session cookie. Secure restricts it to HTTPS. HttpOnly hides it from JavaScript, so an XSS bug cannot read it. SameSite=Strict or Lax stops it being sent on most cross-site requests, which blocks many CSRF attacks; Chrome treats cookies without SameSite as Lax. The __Host- prefix forces Secure, Path=/, and no Domain, locking a cookie to one origin. The Partitioned attribute (CHIPS) keys a third-party cookie to the top-level site. Browsers typically allow about 4 KB per cookie. Third-party tracking cookies are heavily restricted in Safari and Firefox. Google abandoned plans to remove them from Chrome and retired its Privacy Sandbox APIs in October 2025, but they remain subject to user controls and privacy laws such as GDPR and ePrivacy consent rules.
When to Use Cookies
Use a cookie when the server needs a value on every request without client code attaching it, above all for session identifiers. Mark session cookies HttpOnly, Secure, and SameSite=Lax (or Strict), and prefer the __Host- prefix. Keep cookies small, because every request to the domain carries them, including image and CSS requests. Do not use cookies for bulk client-side data; localStorage or IndexedDB fit that better. For APIs called from other origins, cookies require CORS with credentials and SameSite=None; Secure, which reopens CSRF risk, so bearer tokens in an Authorization header are often simpler. Non-essential cookies, such as analytics or advertising, usually need user consent in the EU and UK.
Cookies in Practice
- A hardened session cookie that JavaScript cannot read, is HTTPS-only, and is locked to the exact origin: Set-Cookie: __Host-sid=8f2c1e9a; Path=/; Secure; HttpOnly; SameSite=Lax; Max-Age=86400
- Deleting a cookie by overwriting it with the same name, path, and domain and an expiry in the past: Set-Cookie: theme=; Path=/; Max-Age=0
- An embedded support chat widget on many customer sites uses a Partitioned cookie so each site gets its own isolated chat state instead of a cross-site identifier: Set-Cookie: __Host-chat=abc; Secure; Path=/; SameSite=None; Partitioned
- A login flow breaks after a redirect from an identity provider because the session cookie is SameSite=Strict; switching to Lax allows it on top-level GET navigations while still blocking cross-site POSTs.
Common Mistakes
- Storing session tokens in cookies without HttpOnly, letting any XSS bug read and exfiltrate them. Set HttpOnly on anything used for authentication.
- Setting SameSite=None without Secure. Browsers reject such cookies; SameSite=None requires Secure.
- Assuming SameSite fully replaces CSRF tokens. Lax still allows top-level GET navigations and same-site subdomains can send requests; keep state-changing actions on POST and use tokens for sensitive forms.
- Setting Domain=example.com when only one host needs the cookie, which exposes it to every subdomain. Omit Domain or use the __Host- prefix.
- Packing JSON user profiles into cookies, bloating every request and hitting the ~4 KB limit. Store an ID and keep data server-side.

