Glossary

SameSite cookie attribute

The `SameSite` attribute tells a browser whether to attach a cookie to requests originating from another site. It exists because the web's default — sending cookies on every request to a domain, whoever triggered it — is what makes cross-site request forgery possible. Three values are defined: `Strict`, `Lax` and `None`, and browsers now treat a cookie with no attribute as `Lax`, which changed the default behaviour of the web.

The three values

`Strict` — the cookie is never sent on any cross-site request, including a plain link from another site. A visitor arriving from a search result appears logged out until they navigate within the site.

`Lax` — the cookie is sent on top-level navigations using safe methods, which means following a link works, and it is withheld from cross-site form posts, iframes, images and script-initiated requests.

`None` — the cookie is sent on every cross-site request, as the web historically behaved. It requires the `Secure` attribute, and a cookie declaring `SameSite=None` without it is rejected outright.

A cookie with no attribute is treated as `Lax` by current browsers, which means most cookies now have forgery protection without anyone configuring it.

What site means here

Not origin. Two URLs are same-site when they share the registrable domain, so `app.example.com` and `www.example.com` are the same site despite being different origins.

The scheme is part of it in current browsers: `http://example.com` and `https://example.com` are treated as different sites for this purpose.

A request is cross-site when the site of the page that initiated it differs from the site of the request's destination.

This is a deliberately different boundary from the same-origin policy, and confusing the two is the usual source of surprise when a cookie does or does not appear.

What it defends and what it costs

Cross-site request forgery: an attacking page submitting a form to your site relies on the visitor's session cookie being attached. Under `Lax` it is not, because a cross-site POST does not qualify.

It is defence in depth rather than a replacement for anti-forgery tokens, which do not depend on browser behaviour.

`Strict` breaks the experience of arriving from an external link while logged in, which is why a common pattern is a `Strict` cookie for state-changing operations alongside a `Lax` session cookie.

`None` is needed by genuine cross-site use: an embedded widget, a payment iframe, a federated login that posts back. Those cookies are exactly the ones browsers are restricting further as third-party cookie support is withdrawn.

How to check it

`curl -I https://example.com | grep -i set-cookie` shows the attribute as sent, and its absence is as informative as its presence.

The browser's Application panel has a SameSite column for every stored cookie.

The console warns when a cookie is rejected for declaring `None` without `Secure`, and when a cookie is withheld because of the default.

Test an authenticated flow that starts on another site — a payment return, a login callback — since that is where a change to this attribute is felt.

Frequently asked questions

What is the default if SameSite is not set?
Current browsers treat it as Lax. Historically the absence meant the cookie was sent on every cross-site request.
Why is my SameSite=None cookie rejected?
Because it lacks the Secure attribute. Browsers require the two together, and reject the cookie outright otherwise.
Does SameSite replace CSRF tokens?
No. It is defence in depth that depends on browser behaviour. Anti-forgery tokens do not, and both are worth having.

Sources

Related

VeriFixScan crawls a site and applies its checks to every page it reaches, keeping the evidence behind each finding. Scanning one website is free.

Scan a website