Set-Cookie: attributes, SameSite and cookie prefixes
Set-Cookie stores one cookie in the browser, with attributes controlling its lifetime, which requests it is attached to, and whether page code can read it.
At a glance
- Direction
- Response only, and one cookie per header line.
- Defined in
- RFC 6265, with RFC 6265bis in progress
- When absent
- No cookie is stored, and any existing one for that name keeps its previous value.
- One per header
- Several cookies mean several Set-Cookie lines, never one combined line.
- SameSite
- Lax is the browser default. None allows cross-site sending and requires Secure.
- Lifetime
- Max-Age in seconds takes precedence over an Expires date where both are present.
- __Host- prefix
- Requires Secure, Path=/ and no Domain, which locks the cookie to one exact host.
In detail
HttpOnly and Secure are the two attributes to reach for first. HttpOnly hides the cookie from page code, so an injected script cannot read a session identifier, and Secure stops it ever being sent over plain HTTP. Neither costs anything on a session cookie, and their absence is what turns a scripting bug into a full account takeover.
SameSite decides whether the cookie rides along on requests started by other sites. Lax, now the default, sends it on top level navigation but not on a cross-site image or form post, which stops most request forgery on its own. None restores the old behaviour and is only accepted alongside Secure, so an embedded widget that needs its cookie has to be served over HTTPS.
Scope is set by Domain and Path. Omitting Domain is the tighter choice: the cookie is then bound to the exact host that set it, whereas naming a domain shares it with every subdomain, including any a colleague spins up. Path scoping is a convenience rather than a security boundary, since pages on the same origin can reach each other.
The two prefixes make the scope verifiable. A name starting with __Secure- is only accepted with the Secure attribute, and one starting with __Host- also requires Path=/ and no Domain, which means a cookie with that prefix cannot have been set by a sibling subdomain. That is the only way a server can be sure of a cookie's origin, given that attributes never come back.
Examples
Set-Cookie: __Host-session=8f2b91ac; Path=/; Secure; HttpOnly; SameSite=Lax; Max-Age=86400Set-Cookie: widget_state=collapsed; Secure; SameSite=None; Partitioned; Max-Age=2592000SameSite=None is refused without Secure. The Partitioned attribute keeps the cookie separate per embedding site.
Set-Cookie: session=; Path=/; Max-Age=0The path and domain must match the original exactly, or the browser deletes nothing.
Things that catch people out
- SameSite=None without Secure is rejected outright, so the cookie is not stored at all and the failure looks like the server never sent it.
- Deleting a cookie requires the same Path and Domain it was set with. A mismatch leaves the old cookie in place and adds a second one.
- Setting a Domain attribute shares the cookie with every subdomain, which is wider than most people intend.
- Combining several cookies into one Set-Cookie line does not work. Each cookie needs its own header line.
Try it: HTTP Headers Checker
Check a live URL or paste headers you already have. It grades six security headers from A+ to F and lists every other header the response returned.
HTTP Headers Checker
LOCAL · Browser-OnlyView HTTP response headers for any URL
Enter any website URL to fetch and analyze its HTTP response headers. We'll automatically add https:// if needed.
Why Check Security Headers?
Security headers protect your website against common attacks like XSS, clickjacking, and MIME sniffing. They're set by your web server and cost nothing to implement. Missing security headers are one of the most common findings in security audits.
Related HTTP headers
All http headers →Cookie: what the browser sends back
How the Cookie header is formatted, why attributes never come back, how the browser decides which cookies to include, and what the size limits are.
Clear-Site-Data: wiping browser state on logout
How Clear-Site-Data clears cookies, storage and caches for your origin, which directives are safe on a logout response, and where support is uneven.
Access-Control-Allow-Credentials: cookies across origins
What credentials mode means, the three wildcards it disables, what the client must also do, and why this header needs an exact origin in the response.
Strict-Transport-Security: the HSTS response header
What Strict-Transport-Security does, what max-age and includeSubDomains change, why preload is close to permanent, and how to withdraw the policy safely.
Host: which site the request is for
Why Host is mandatory in HTTP/1.1, how it maps to the authority in HTTP/2 and HTTP/3, and why trusting it to build URLs creates a real vulnerability.
Location: where the client should go next
How Location works on each 3xx status, why it also appears on a 201 Created, whether relative URLs are allowed, and how to avoid an open redirect.
Tools for this
- HTTP Headers Checker Free online HTTP headers checker - view HTTP response headers for any URL
- HTTP Request Builder Free online HTTP request builder - build and test HTTP requests with custom headers and body