EMZETT.
Login

Cookies

In short: Small pieces of data that a web server stores in a user’s browser and automatically receives back with every further request to the same site — the basis for sessions and login states in stateless HTTP.

In more detail: Since HTTP is stateless by nature (each request is independent, the server doesn’t “remember”), a mechanism is needed to recognise a user across several requests — cookies were invented for this. Important security attributes: HttpOnly (not readable via JavaScript, protects against XSS theft), Secure (only sent over HTTPS) and SameSite (restricts with which cross-site requests the cookie is sent, protects against CSRF).

In Depth

A server sets a cookie via the Set-Cookie response header, and the browser then automatically sends it along with every further request to the same domain:

Set-Cookie: session_id=a3f9c2...; HttpOnly; Secure; SameSite=Lax; Max-Age=3600; Path=/

Each attribute has a concrete security function:

  • HttpOnly — the cookie can’t be read via document.cookie (JavaScript). Prevents a script injected via cross-site scripting (XSS) from stealing the session cookie and sending it to an attacker.
  • Secure — the browser sends the cookie exclusively over an encrypted HTTPS connection, never over unencrypted HTTP.
  • SameSite=Strict/Lax/None — controls whether the cookie is sent with requests triggered by ANOTHER website. Strict blocks this completely, Lax only allows it for simple navigations (e.g. clicking a link), None allows it without restriction (and then strictly requires Secure). Protects against cross-site request forgery (CSRF), in which a malicious website tries to send requests to another site on behalf of the logged-in user.

A distinction is also made between session cookies (without Max-Age/Expires, they disappear when the browser is closed) and persistent cookies (with a fixed expiry time, they survive restarts). Third-party cookies (set by a domain other than the one visited, e.g. for tracking across several websites) are increasingly blocked by default by modern browsers.

First-party vs. third-party cookies

The difference is crucial for privacy and tracking: a first-party cookie is set by the domain the user is actually visiting (e.g. shop.example.com sets a cart cookie for itself) — this is technically necessary and unproblematic. A third-party cookie, on the other hand, is set by ANOTHER domain that loads as an embedded resource on the visited page (e.g. an advertising network script) — this cookie lets the same advertising company recognise the user on thousands of different websites and build a comprehensive user profile from this. Chrome, Safari and Firefox have increasingly restricted or completely blocked third-party cookies in recent years, which is forcing the advertising industry towards alternative (sometimes more privacy-friendly) tracking methods.

Browsers limit the size and number of cookies per domain (usually 4 KB per cookie, about 50-180 cookies per domain depending on the browser) — that’s why modern applications usually only store a short, random session ID in the cookie, while the actual user data is stored on the server (database, Redis) under this ID, instead of being transported directly in the cookie.

In the EU, in addition to the GDPR, the ePrivacy Directive (colloquially the “cookie directive”) stipulates that active consent must be obtained from the user for cookies that aren’t technically necessary (i.e. practically everything except session/security cookies) before they may be set — the ubiquitous cookie banners on European websites are the direct consequence of this rule. Purely functional cookies (e.g. a cart cookie or a session cookie for the login), on the other hand, don’t require consent, because they’re technically essential for the requested function.

See also: Session, HTTPS