skip to content

questions

15

What is the difference between a cookie sent as 'Set-Cookie: sid=abc' and one sent as 'Set-Cookie: sid=abc; Max-Age=3600', in terms of how long the browser keeps it?

level: juniorimportance: must knowfreq 58%

answer

  1. no Expires and no Max-Age = session cookie
  2. Max-Age/Expires present = persistent, on disk
  3. 'session' is the browser's definition, not yours
  4. session restore can outlive a browser close
  5. cookie lifetime != server-side session validity

basics

~20 s

With no Max-Age or Expires it is a session cookie: held in memory and dropped when the browsing session ends. With Max-Age=3600 it is persistent: written to disk and sent for one hour, surviving browser restarts.

solid answer

~50 s

A `Set-Cookie` with **neither `Expires` nor `Max-Age`** creates a **session cookie**. The browser keeps it only for the current browsing session — typically in memory — and discards it when the browser closes. `Set-Cookie: sid=abc; Max-Age=3600` creates a **persistent cookie**: the browser records an expiry time (now plus 3600 seconds), stores it durably, and keeps sending it until that moment passes, across restarts.\n\nTwo caveats matter in practice. First, "session" is the *browser's* notion, not your server's: modern browsers restore session cookies when they reopen tabs after a crash or with "continue where you left off" enabled, so a session cookie can outlive a visible close. Second, neither kind is guaranteed — a browser may evict a cookie early under storage pressure or user clearing. Server-side session state should therefore have its own expiry; the cookie lifetime is a hint, never the authority on whether a session is still valid.

code

http · 1 line
http
HTTP/1.1 200 OK\nSet-Cookie: sid=abc123; Path=/; HttpOnly; Secure; SameSite=Lax\nSet-Cookie: theme=dark; Path=/; Max-Age=3600

go deeper

for a junior

State the rule plainly: no lifetime attribute means it dies with the browser session; Max-Age or Expires makes it persist on disk.

for a middle

Add that 'session' is defined by the browser, mention session restore and incognito, and note that Max-Age is relative while Expires is absolute.

for a senior

Tie it to auth design: short session cookie plus rotated persistent refresh cookie, server-side expiry as the authority, graceful degradation when the cookie is gone.

for a principal

Frame the tradeoff between friction and risk across device classes, and set organisation-wide policy for remember-me lifetime, revocation and session invalidation.

## Two lifetimes, one header\n\nEvery cookie is either a *session cookie* or a *persistent cookie*, and the only thing that decides which is the presence of a lifetime attribute on `Set-Cookie`.\n\n- **No `Expires`, no `Max-Age`** → session cookie. The user agent keeps it for "the current session" and discards it at the end.\n- **`Max-Age=<seconds>` or `Expires=<HTTP-date>` present** → persistent cookie. The browser computes an absolute expiry time, stores the cookie durably (on disk), and sends it on matching requests until that time passes.\n\n```\nSet-Cookie: sid=abc; Path=/; HttpOnly <- session cookie\nSet-Cookie: sid=abc; Path=/; Max-Age=3600; HttpOnly <- persistent, one hour\n```\n\n## What "session" actually means\n\nThe session is defined by the **user agent**, not by your application and not by the protocol. It roughly means "until the browser process for this profile exits". That definition leaks in ways that surprise people:\n\n- **Session restore.** Chrome, Firefox and Edge routinely persist session cookies across a restart when the user has "reopen tabs" configured, or after a crash recovery. A session cookie can therefore survive a full close and reopen — you cannot rely on it disappearing.\n- **Mobile.** On iOS and Android, browsers are suspended rather than exited for days. The session may last far longer than a desktop one.\n- **Multiple windows.** All windows of the same profile share one cookie store; closing one window ends nothing. Private/incognito windows have a **separate** store that is destroyed when the last such window closes.\n\nSo "session cookie" is a good default for login state on shared machines, but it is a usability preference, not a security control.\n\n## Why persistence is a product decision\n\nA session cookie means the user logs in again after a restart. A persistent cookie means "remember me". The pattern most applications use:\n\n- Short-lived **access/session cookie** — often a session cookie, or a persistent one with a small `Max-Age` (minutes).\n- Longer-lived **refresh/remember-me cookie** — persistent, with `Max-Age` in days or weeks, marked `HttpOnly` and `Secure`, and rotated on each use so theft is detectable.\n\nEither way the server keeps its own expiry for the underlying session record. The cookie's lifetime governs whether the *browser sends* the credential; only server-side state governs whether the credential is still *valid*. Anyone who treats the cookie lifetime as the session timeout has built a system where a stolen cookie is valid for as long as the attacker keeps it — the client's clock and the client's storage are not yours to trust.\n\n## The absolute-time trap\n\n`Max-Age` is relative (seconds from receipt); `Expires` is an absolute HTTP-date. A persistent cookie's expiry is evaluated against the **client's** clock, so a device whose clock is wrong by a day will expire cookies early or late. `Max-Age` is largely immune to this because the browser converts it to an absolute time at receipt using its own clock, so only clock *drift* during the lifetime matters rather than absolute skew.\n\n## Nothing is guaranteed\n\nA persistent cookie is best-effort storage. It can vanish before its expiry because the user cleared browsing data, because the browser evicted it under per-domain or global cookie limits, because storage pressure triggered cleanup, or because a privacy policy capped its lifetime. Applications must therefore degrade gracefully: a missing cookie means "treat as anonymous and re-authenticate", never an error state, and never irreversible data loss (do not store the only copy of anything in a cookie).\n\n## Quick decision guide\n\n- Kiosk or shared terminal, or highly sensitive app → session cookie, plus a short server-side idle timeout.\n- Consumer app with "keep me signed in" → persistent cookie with an explicit `Max-Age`, user-visible and revocable server-side.\n- Anything non-essential (theme, last-used tab) → persistent, small `Max-Age`, and code that works fine when it is gone.

  • If a session cookie can survive a browser restart via session restore, is it still worth using one for login?
    Yes, as a default that matches user expectation on shared machines, but not as a security boundary. Pair it with a server-side idle timeout and absolute session lifetime so that the authoritative expiry lives on the server, where session restore, clock changes and cookie-store quirks cannot affect it.
  • Should the session cookie's lifetime be the session timeout?
    No. The cookie lifetime only controls whether the browser keeps sending the credential; the server must independently track when the session expires and reject stale ones. Otherwise a cookie copied off the machine stays valid indefinitely, since the attacker simply never lets it expire in their own store.

A session cookie is a paper wristband at a venue — it exists only while you are inside tonight. A persistent cookie is a membership card in your wallet with a printed expiry date, still there next month.

saying these in an interview costs you the question

  • Believing a session cookie is always destroyed when the browser closes
  • Treating the cookie's Max-Age as the authoritative session timeout with no server-side expiry
  • Thinking a persistent cookie is guaranteed to exist until its expiry
  • Confusing 'session cookie' with a cookie whose name happens to be sessionid
  • Assuming incognito shares the normal cookie store

context

open as a page

What is the difference between an HTTP cookie set without a Domain attribute and one set with `Domain=example.com`, and which hosts will the browser send each one to?

level: juniorimportance: must knowfreq 60%

basics

~10 s

No Domain means host-only: sent only to the exact host that set it. Domain=example.com means sent to example.com and every subdomain of it. Counter-intuitively, omitting Domain is the narrower, safer scope.

open as a page

What do the `Secure` and `HttpOnly` attributes on an HTTP Set-Cookie header do, and which attack does each one address?

level: juniorimportance: must knowfreq 70%

basics

~20 s

Secure tells the browser to send the cookie only over HTTPS, protecting it from network eavesdroppers. HttpOnly hides it from JavaScript's document.cookie, so cross-site scripting cannot read and exfiltrate it. Session cookies should carry both.

open as a page

When an HTTP 'Set-Cookie' header carries both Max-Age and Expires, which one wins, and how do you correctly delete a cookie you set earlier?

level: middleimportance: must knowfreq 48%

basics

~20 s

Max-Age wins when both are present. To delete, resend Set-Cookie with the same name and the same Domain and Path, plus Max-Age=0 (or an Expires date in the past). If the scoping attributes do not match, you create a second cookie instead of removing the first.

open as a page

Explain what `SameSite=Strict`, `SameSite=Lax` and `SameSite=None` each do to when a browser sends a cookie, and when you would choose each.

level: middleimportance: must knowfreq 65%

basics

~20 s

SameSite controls whether a cookie rides on cross-site requests. Strict: never on cross-site requests, including top-level links. Lax: only on top-level, safe-method navigations such as clicking a link, not on cross-site POSTs, iframes, images or fetches. None: always sent, and it must also be Secure.

open as a page

How much data can you actually store in a single HTTP cookie, roughly how many cookies will a browser keep per domain, and what happens when you exceed those limits?

level: juniorimportance: should knowfreq 45%

basics

~20 s

Roughly 4096 bytes for the whole Set-Cookie name plus value (attributes count in modern browsers), and at least 50 cookies per domain — Chrome allows about 180. Over the limit the browser silently ignores the Set-Cookie or evicts old cookies; you get no error.

open as a page

Why must multiple HTTP 'Set-Cookie' response headers never be folded into a single comma-separated header line, and what does that imply for HTTP client library APIs?

level: middleimportance: should knowfreq 34%

basics

~20 s

The Expires attribute uses an HTTP-date that itself contains a comma ('Wed, 09 Jun 2027 10:18:14 GMT'), so comma-joining Set-Cookie values is ambiguous and cannot be split back reliably. Client libraries must expose a get-all-values API; a single getHeader('Set-Cookie') loses cookies or corrupts them.

open as a page

What do the `__Host-` and `__Secure-` name prefixes on an HTTP cookie mean, and what do browsers enforce when they see them?

level: middleimportance: should knowfreq 45%

basics

~20 s

They are cookie-name conventions browsers enforce. __Secure- makes the browser reject the Set-Cookie unless it has the Secure attribute and came over HTTPS. __Host- adds two rules: no Domain attribute and Path=/, so the cookie is host-only and no subdomain can set it.

open as a page

How does the `Path` attribute on an HTTP cookie decide when the browser sends it, and why is Path not treated as a security boundary?

level: middleimportance: should knowfreq 40%

basics

~20 s

Path is a prefix match on directory segments: Path=/admin sends the cookie to /admin and anything under it. It is not a security boundary because same-origin JavaScript from any path can read and write cookies for other paths.

open as a page

Your application sets a cookie with 'Set-Cookie: prefs=x; Max-Age=31536000' and expects it a month later, yet some users lose it. What browser behaviours remove a cookie before its stated expiry, and how do you design around that?

level: seniorimportance: should knowfreq 26%

basics

~20 s

Cookies are best-effort storage. Browsers cap lifetimes (roughly 400 days, and far less for script-set cookies under some privacy engines), evict by least-recently-used when per-domain or total cookie limits are hit, clear on user or policy action, and drop everything in private mode. Treat cookies as a cache, keep the truth server-side, and refresh on use.

open as a page

Under RFC 6265, when does a new 'Set-Cookie' replace an existing cookie versus create a second cookie with the same name, and what does the client send if two same-named cookies both match a request?

level: seniorimportance: should knowfreq 30%

basics

~20 s

A cookie's identity is the triple name, Domain, Path. A Set-Cookie matching all three replaces the old value in place, keeping its creation time. Differ in any one and you get a second cookie; both are then sent in the Cookie header, longest path first, and the server cannot tell them apart.

open as a page

Some users of a web app suddenly get HTTP 431 Request Header Fields Too Large (or a 400 from the CDN) on every request, and clearing cookies fixes it. How do you diagnose and permanently fix this?

level: seniorimportance: should knowfreq 30%

basics

~20 s

Accumulated cookies pushed the Cookie request header past the proxy or server header limit. Measure total cookie bytes per user, find the writer that keeps adding cookies, cap and expire them, shrink the session cookie to an opaque id, and serve assets from a cookieless host.

open as a page

Browsers changed the default for cookies with no SameSite attribute from 'send everywhere' to Lax, and began rejecting `SameSite=None` without `Secure`. What broke as a result, and how do you handle it?

level: seniorimportance: should knowfreq 40%

basics

~20 s

Cookies with no SameSite now behave as Lax, so anything relying on cross-site delivery broke: embedded iframes, cross-site POST callbacks, SSO and payment redirects that POST back, and third-party widgets. The fix is to mark genuinely cross-site cookies SameSite=None; Secure — and to set SameSite explicitly everywhere instead of relying on defaults.

open as a page

Why will a browser refuse a Set-Cookie with `Domain=co.uk` from a page on `shop.example.co.uk`, and why is there no way for example.com to set a cookie that another-site.com will send?

level: seniorimportance: nice to knowfreq 28%

basics

~20 s

Browsers use the Public Suffix List to block cookies scoped to a registry-controlled suffix like co.uk, which would otherwise leak across unrelated sites. And a cookie's Domain must domain-match the setting host, so cross-registrable-domain cookies are impossible by construction.

open as a page