Use Lax for most session cookies, Strict for cookies that guard high risk actions and never need to arrive on a link from another site, and None only when a cross-site context truly needs the cookie. None also requires the Secure attribute. If you set nothing, browsers treat the cookie as Lax.
What the three values do
Strict sends the cookie only on requests that start from the cookie's own site. Click a link to your app from an email and the first page load arrives without the cookie, so the user looks logged out until the next request.
Lax also sends the cookie when the user navigates to your site from elsewhere, for example by clicking a link. It still withholds the cookie from cross-site subrequests such as images, frames and most form posts.
None sends the cookie on same-site and cross-site requests alike. MDN states that SameSite=None must be paired with Secure, which means the cookie travels only over HTTPS.
A simple way to choose
Ask what the cookie is for.
- Login session on an ordinary web app:
Lax. Users follow links into the app all the time and expect to stay signed in. - A separate cookie for a payment or admin area that is only reached from inside your own pages:
Strictis a reasonable extra layer. - An embedded widget, a single sign on flow that posts across sites, or a payment iframe:
None; Secure, and keep the cookie as narrow as you can. - Anti tracking or preference cookies that nothing cross-site reads: leave them
LaxorStrict.
Write the attribute explicitly even when you want the default. It documents intent and avoids surprises with older clients.
Set-Cookie: __Host-session=abc123; Secure; HttpOnly; Path=/; SameSite=Lax
The __Host- prefix adds protection of its own. MDN notes it requires Secure, no Domain attribute and Path=/, so the cookie is bound to the exact host that set it.
What SameSite does not fix
SameSite limits when the browser attaches a cookie. It is not a full replacement for CSRF defences. The OWASP CSRF cheat sheet lists several gaps: Lax still allows cookies on top level navigations that use safe methods, so any state changing GET endpoint stays exposed. The setting is scoped to the registrable domain, so sibling subdomains count as same-site. It does not cover client side CSRF, and some older browsers do not enforce it.
For that reason treat SameSite as one layer. Keep CSRF tokens or a custom header requirement on state changing requests, and never change state on GET.
Quick check
Is Strict always more secure than Lax?
It blocks more cross-site sending, but it also breaks the first page load after a click from another site. For a normal login session that cost is usually not worth it, and CSRF tokens do the heavier lifting.
Why does my SameSite=None cookie get rejected?
Most often the Secure attribute is missing, or the page is served over plain HTTP. None requires a secure context.
Sources
Last reviewed: 19 October 2026.