Guide
Auditing cookie flags: Secure, HttpOnly, SameSite and prefixes
Cookies hold the things that identify a signed-in user, so a flaw in how they are set is a direct path to account takeover. Their protections are not switched on by default; each one is an attribute you add to the Set-Cookie header. This auditor reads the headers your application sends and tells you, cookie by cookie, which protections are missing and why they matter.
The attributes
Secure keeps the cookie off plain HTTP, where anyone on the network could read it. HttpOnly hides it from JavaScript, so injected script cannot copy a session identifier. SameSite decides whether the cookie travels with requests started by other sites: Strict never sends it cross-site, Lax sends it on simple navigations, and None sends it everywhere and requires Secure. Domain widens a cookie to the domain and all subdomains, which is rarely what you want. Path, Max-Age and Expires set scope and lifetime. The prefixes __Host- and __Secure- make browsers enforce rules: __Host- requires Secure, Path=/ and no Domain, which locks the cookie to the exact host.
A worked example
Press Sample to load four cookies and the page grades them F with a score of 0 out of 100. The cookie sessionid has only a path: it lacks Secure and HttpOnly (both High), has no SameSite (Medium, because older browsers send it cross-site), could use the __Host- prefix, and is a session cookie with no lifetime. The cookie __Host-token does well: Secure, HttpOnly, SameSite=Strict and an honoured prefix are all Good, with notes that its value is a JWT, which anyone with the cookie can read, and that it ends with the browser session. The cookie tracker has SameSite=None without Secure, which browsers reject, so it is dropped, plus a wide Domain=example.com. The fourth, theme, is a preference cookie with Secure and SameSite=Lax; its only finding is a Low note that HttpOnly is missing, which does no harm for a value that scripts read.
What browsers do on their own
Current browsers treat a cookie without SameSite as Lax, but older ones do not, so state the value. Browsers cap the lifetime of a cookie at 400 days, whatever Max-Age you set. A cookie set with SameSite=None must also be Secure or it is discarded. These rules explain why a cookie that “works in the test environment” disappears in production.
Reading names and values
The auditor judges a cookie more strictly if its name suggests a session, token or login (names containing sess, auth, token, jwt, sid, login, csrf, xsrf, remember or user). It also looks at the value: a JWT in a cookie is flagged because the payload is readable by anyone who holds the cookie, so sensitive claims should not be in it and the lifetime should be short.
Fixing findings
Add Secure; HttpOnly; SameSite=Lax to session cookies as a baseline, use Strict for sensitive actions, and rename the session cookie to __Host-session where your framework allows. Do not set Domain unless you need sharing across subdomains. Keep lifetimes as short as the product allows.
Limits
The page cannot know what each cookie is used for, so a name it does not recognise is judged only by its flags. Only the Set-Cookie header shows the flags; a Cookie request header carries just names and values. Browser behaviour keeps evolving. Cookie values pasted here stay on your device.
Related tools
- Security Headers Generator and Auditor grades cookies together with other headers.
- Cookies.txt to JSON converts exported cookie files.
- CORS Header Generator and Tester covers credentialed cross-origin requests.
- JWT Decoder reads the token in a cookie value.
Checked against the current version of the Cookie Security Auditor on .

