Learn · RFC 6265bis
Cookie flags
Secure, HttpOnly and SameSite: the three attributes that decide who can read or send a cookie.
A session cookie is a password for as long as it lives. Whoever holds it is the logged-in user. Three attributes on the Set-Cookie header decide where the browser will send it and who can read it, and leaving them off is one of the commonest ways a small bug becomes an account takeover.
Set-Cookie: session=abc123; Path=/; Secure; HttpOnly; SameSite=Lax
- Secure — the browser only sends the cookie over HTTPS. Without it, the cookie is sent in clear text on any plain HTTP request to the site, including one an attacker induces the browser to make.
- HttpOnly — scripts running on the page cannot read the cookie. If an attacker finds a cross-site scripting flaw, they cannot simply copy the session out. Use it on every cookie the front end does not need to read.
- SameSite — controls whether the cookie is sent on requests started by other sites. Lax sends it on top-level navigations such as clicking a link but not on background requests like form posts and images, which blocks most cross-site request forgery. Strict never sends it cross-site. None sends it always, and requires Secure.
Scope: Domain and Path
A cookie with no Domain attribute is sent only to the exact host that set it. Setting Domain=example.com makes it visible to every subdomain, including ones run by other teams or pointing at third-party services, so only do that when you must share a session. The __Host- name prefix goes further: the browser refuses to accept a cookie so named unless it is Secure, has Path=/ and has no Domain, which guarantees it was set by this exact host over HTTPS.
Set-Cookie: __Host-session=abc123; Path=/; Secure; HttpOnly; SameSite=Lax
Common failure modes
- Relying on the browser default for SameSite. Chrome treats a cookie with no SameSite as Lax, but that is not true of every browser or version, so set it explicitly.
- Setting HttpOnly on the session cookie but leaving other sensitive cookies, such as a CSRF token that the page does not need to read, readable by scripts.
- Using SameSite=None for convenience, for example to support an embedded widget, and then keeping it for everything.
- A long-lived cookie with no expiry policy on the server, so a stolen one stays valid for months.
Surface reads the Set-Cookie headers of your homepage response. Cookies set only after login or on other pages are not visible to it, so a clean result here is a good sign but not a full audit of your application.
Is your domain actually covered?
Surface checks Cookie flags — and everything else on this page — against your real DNS and headers, free, in seconds.
Scan your domain →