HTTP Cookies Table

AttributeWhat it controlsField note
Name=ValueThe cookie pair itselfNames are case-sensitive; $-prefixed names are reserved
Expires=dateFixed expiry (GMT format)Omit it and the cookie is session-only - dies with the tab
Max-Age=3600Expiry in secondsWins over Expires when both are set; modern default
Domain=site.comWhich hosts receive itCannot be a different site; sets parent-domain sharing
Path=/Which paths receive it/ = everywhere; a narrower path does NOT hide the cookie from JS
SecureHTTPS-only transmissionNever sent over http: - table stakes for anything sensitive
HttpOnlyHidden from document.cookieThe XSS dam - JavaScript cannot read it, only the browser sends it
SameSite=Lax|Strict|NoneCross-site sending policyLax is the modern default; None requires Secure
Reference: the MDN Set-Cookie reference. The two attributes that do the security work: HttpOnly hides the cookie from JavaScript so an XSS cannot exfiltrate a session, and SameSite=Lax (the browser default since 2020) stops other sites from sending your cookie in their requests - which kills most CSRF by default. Bottom line: session cookies want HttpOnly; Secure; SameSite=Lax, and Max-Age shorter than the risk. Note what cookies are NOT for: storage - the 4KB ceiling and per-request transmission make them identity, not database. Related tools: web storage table for localStorage vs cookies, HTTP caching table for the other Set-Cookie neighbor, and fetch table for the credentials that carry them.

Cookies are the web's original state mechanism: the server sends Set-Cookie headers, the browser stores the pairs, and every matching request carries them back. The table below is the working eight - the attributes that decide a cookie's lifetime, scope and security - with the field notes that separate identity storage from misuse.

Bottom line: two attributes do the security work. HttpOnly hides the cookie from document.cookie so an XSS cannot exfiltrate the session, and SameSite=Lax (the browser default since 2020) stops other sites from sending your cookie in their requests - killing most CSRF by default. A session cookie wants all three of HttpOnly, Secure and SameSite=Lax, plus a Max-Age shorter than the risk.

The honest part: cookies are identity, not storage. The 4KB-per-cookie ceiling, per-request transmission (every cookie rides every matching request, both directions), and the JS visibility (unless HttpOnly) make them the wrong database. Web storage table's localStorage handles client-only data; cookies should carry exactly one thing: the credential that says who you are.

How to use

  1. Set cookies server-side with Set-Cookie; read the security triple first: HttpOnly, Secure, SameSite.
  2. Pick the lifetime deliberately: session-only (omit both Expires and Max-Age) for login tabs, Max-Age for durable remember-me.
  3. Scope narrowly: default Path=/ and no Domain attribute unless a parent-domain share is genuinely needed.

Frequently asked questions

What is the difference between Expires and Max-Age?

Both end a cookie's life: Expires is a fixed GMT date, Max-Age is a seconds-from-now count. When both are set, Max-Age wins in every modern browser. Omitting both creates a session cookie that dies when the browser closes - which is the correct choice for login sessions that should not outlive the tab. The legacy gotcha: Expires wants the RFC 1123 GMT format (Wdy, DD Mon YYYY HH:MM:SS GMT); get it wrong and some browsers drop the attribute.

What do HttpOnly and SameSite actually protect against?

Different attacks. HttpOnly blocks JavaScript from reading the cookie (document.cookie simply omits it), which contains the damage of an XSS - the attacker can act as the user in the browser but cannot carry the session token away. SameSite controls cross-site sending: Lax allows the cookie only on top-level navigations from other sites, which defuses CSRF, because a forged form POST from evil.example no longer carries your session. The two stack; neither substitutes for the other.

Does the Path attribute hide a cookie from other paths?

No - this is the classic misunderstanding. Path only decides which REQUESTS carry the cookie, not what JavaScript can read: document.cookie on any page of the site sees every cookie for the domain regardless of Path. A cookie set with Path=/admin is still visible to JavaScript on /public. If the goal is isolation, Path cannot provide it - HttpOnly and server-side checks do.

Should I use cookies or localStorage for my app's data?

localStorage for client-only data, cookies for the credential. Cookies ride every matching HTTP request in both directions (bandwidth and latency cost), cap around 4KB, and are readable by the server - built for carrying identity. localStorage stays client-side, holds megabytes, and never auto-sends - built for data the server doesn't need on every request. The one thing cookies do that localStorage cannot: reach the server automatically and be hidden from JavaScript via HttpOnly.

Related tools