TL;DR / The SameSite cookie attribute controls whether cookies are sent on cross-site requests, with
Strictblocking them entirely,Laxallowing them on top-level navigations, andNonepermitting them everywhere (but requiringSecure).
How It Works
Same-site Top nav Cross-site
request (GET) subrequest
┌─────────────┐
│ Strict │ YES NO NO
└─────────────┘
┌───────────────┐
│ Lax (default) │ YES YES NO
└───────────────┘
┌───────────────┐
│ None + Secure │ YES YES YES
└───────────────┘
The SameSite attribute was introduced to address the fact that browsers historically sent cookies on every request to a domain, regardless of which site initiated that request. This default behavior enabled CSRF attacks -- a malicious page could submit a form to your bank, and the browser would attach your session cookie automatically.
Defining "Same-Site"
Before understanding the modes, you need to understand what "same-site" means. It is not the same as "same-origin." Two URLs are same-site if they share the same registrable domain (the effective TLD plus one label). So app.example.com and api.example.com are same-site, but example.com and example.org are not. The scheme also matters in modern browsers -- http://example.com and https://example.com are considered cross-site in "schemeful same-site" implementations.
Strict Mode
SameSite=Strict blocks the cookie on all cross-site requests with no exceptions. If a user follows a link from an email or another website to your app, the cookie is not sent on that initial navigation. The user arrives logged out and must navigate again (or the page reloads) for the cookie to attach. This is the most secure mode but creates a degraded user experience for any inbound link to authenticated content.
Lax Mode
SameSite=Lax is the default in modern browsers (Chrome, Edge, Firefox). It blocks cookies on cross-site subrequests (images, iframes, POST forms) but allows them on top-level navigations using safe HTTP methods (GET, HEAD, OPTIONS). This means clicking a link from another site to your app sends the cookie, preserving the logged-in experience. However, a cross-site form POST does not send the cookie, which blocks the most common CSRF vector.
Lax provides a strong balance between security and usability. Chrome originally shipped a two-minute "Lax+POST" exception that allowed cross-site POST requests to carry newly created cookies. This temporary intervention has been deprecated, so POST requests from cross-site origins reliably omit Lax cookies in current browsers.
None Mode
SameSite=None restores the legacy behavior -- cookies are sent on all requests regardless of site context. This is required for legitimate cross-site use cases like third-party widgets, embedded iframes that need authentication, or federated login flows. The critical constraint is that None requires the Secure attribute, meaning the cookie is only sent over HTTPS. Without Secure, browsers reject SameSite=None cookies entirely.
Browser Default Behavior
When no SameSite attribute is set, modern browsers treat it as Lax. This was a major breaking change when Chrome rolled it out in 2020. Legacy applications that relied on cookies being sent cross-site without explicitly setting SameSite=None; Secure broke. Some older browsers (IE, older Safari) do not support SameSite at all and ignore the attribute, which creates inconsistent behavior across browser versions.
Interaction With Other Defenses
SameSite cookies are a defense-in-depth measure, not a complete CSRF solution on their own. Lax still allows GET-based state changes to receive cookies. If your application modifies data on GET requests (a design flaw, but common in practice), Lax does not protect against CSRF for those endpoints. Combining SameSite with CSRF tokens or checking the Origin header provides comprehensive protection.
Gotchas
SameSite=NonewithoutSecureis silently rejected by modern browsers. The cookie is never stored, and no error is thrown.Strictbreaks inbound links. Users clicking links from emails, Slack, or other sites arrive without their session cookie, appearing logged out.- Subdomains are same-site, so
evil.example.comcan send cookies toapp.example.comunder Lax and Strict. SameSite does not provide subdomain isolation. - The default is
Lax, notNone. Applications relying on cross-site cookies must explicitly setSameSite=None; Secureor they break silently in modern browsers. - Safari has historically had quirks with SameSite handling, including treating unrecognized values as Strict rather than the spec-defined behavior. Test across browsers.