Guide
SameSite Strict, Lax and None Explained
Understand the SameSite cookie attribute, the difference between Strict, Lax and None, and why cross-site requests sometimes arrive without your cookie.
Key takeaways
- SameSite decides whether a cookie is sent on requests that start from another site; the values are Strict, Lax and None.
- A site is the registrable domain, so www.example.com and api.example.com are same-site even though they are cross-origin.
- Lax withholds cookies from most cross-site subrequests but allows top-level GET navigations; it suits ordinary session cookies.
- None sends the cookie everywhere and must be combined with Secure.
- Not every browser defaults to Lax, so set SameSite explicitly, and keep CSRF tokens for sensitive actions.
What is SameSite for?
By default, a browser attaches cookies to a request based on the destination, not on where the request came from. If a page on one website causes the browser to send a request to another website, the cookies for that other website used to go along automatically. That behaviour is what makes cross-site request forgery possible, and it also lets third-party content track people across sites. The SameSite attribute lets a cookie declare whether it should be included on requests that begin from a different site.
What counts as the same site?
Here the word site has a particular meaning. It is the registrable domain, often called the eTLD plus one, so www.example.com and api.example.com belong to the same site. Different ports or different subdomains do not make a request cross-site. This is different from the idea of an origin, which includes scheme, host and port. Two origins can be same-site while still being cross-origin. Keeping this distinction clear avoids many misunderstandings, because SameSite is evaluated on sites, while CORS and the same-origin policy work on origins.
Many browsers also consider the scheme when deciding whether two URLs are same-site, which is sometimes called schemeful same-site. The web.dev guide to same-site and same-origin notes that the definition of a site now includes the scheme, so the HTTP and HTTPS versions of a host count as different sites. MDN adds that a site is the registrable domain: an entry in the Public Suffix List plus the portion just before it. Test any flow that mixes HTTP and HTTPS.
SameSite=Strict
With SameSite=Strict, the cookie is sent only when the request originates from the same site. If a user clicks a link on another website that leads to yours, the first request does not carry the cookie. The page loads as if the user were logged out, and subsequent in-site requests carry it again. This is very protective against forgery, but the user experience cost is visible. Someone who follows a link from an email to a page in your logged-in area may see a login prompt until they refresh or navigate.
Strict suits cookies that guard high-risk actions, for example a cookie used only on an administrative area, where the extra click is acceptable.
SameSite=Lax
With SameSite=Lax, the cookie is withheld on most cross-site subrequests, such as images, frames and background fetches, and on cross-site form posts. It is still sent on top-level navigations that use a safe method such as GET. So a user following a link from another site arrives logged in, while a hidden form on a malicious page that posts to your site does not carry the cookie.
Current browsers generally treat a cookie with no SameSite attribute as Lax. This default was introduced gradually, and there have been small exceptions in how it is applied, for example a short window after a cookie is created during which some cross-site posts may still carry it in certain browsers (MDN describes this as a more permissive Lax that also includes cookies set no more than two minutes before a POST request). Because those details can change, set the attribute explicitly rather than depending on the default. Lax is a good general choice for session cookies.
SameSite=None
With SameSite=None, the cookie is sent in all contexts, including cross-site requests. You need this for legitimate cross-site uses: an embedded widget that must know the user, a payment frame, or an identity provider on another domain. Current browsers require that a cookie with SameSite=None also carries the Secure attribute, otherwise it is rejected. A correct header looks like Set-Cookie: widget=xyz; Secure; SameSite=None; Path=/.
Choosing None re-opens the exposure that SameSite was designed to close, so combine it with other defences such as anti-forgery tokens, and consider whether the cookie should also use the Partitioned attribute, discussed in another guide. Also note that some browsers block or restrict third-party cookies entirely, so SameSite=None does not guarantee that a cookie will be delivered in an embedded context.
SameSite values compared
| Value | Cross-site subrequests (images, frames, fetch) | Top-level GET navigation from another site | Needs Secure |
|---|---|---|---|
| Strict | Not sent | Not sent | No |
| Lax | Not sent (most) | Sent | No |
| None | Sent | Sent | Yes |
Which value should I choose?
- Authentication cookies for an ordinary site: Lax, or Strict if the inconvenience is acceptable.
- Cookies that must work inside embeds or across different sites: None with Secure, accepting the added risk.
- Preference cookies with no security impact: Lax is still fine, and it keeps your intent clear.
How does SameSite relate to CSRF?
SameSite greatly reduces cross-site request forgery for browsers that enforce it, but it is not a complete replacement for other protections. Requests that are same-site yet attacker-influenced, for example via a vulnerable sibling subdomain, are not blocked. Older clients may not support the attribute. And Lax still allows top-level GET navigation to carry the cookie, so state-changing actions must never be performed on GET. Keep using anti-forgery tokens or checks of the Origin header for sensitive operations.
How do I debug a missing cookie?
When a cookie is unexpectedly absent from a request, SameSite is one of the first suspects. Open the network panel in your browser developer tools, select the request, and inspect the request cookies tab. Many browsers show a warning icon with a short reason, such as the cookie being blocked because of its SameSite setting. Compare the site of the page that started the request with the site of the destination. If they differ, check whether your cookie is Lax or Strict, and whether a redirect chain or an embedded frame is involved.
Summary
SameSite gives each cookie a simple stance toward cross-site traffic: none, only on navigation, or only inside the same site. Set it deliberately on every cookie, test the flows that start from other websites, such as links in emails and payment returns, and keep server-side protections in place for state-changing actions.
Sources and further reading
- MDN: Set-Cookie header: each attribute (Domain, Path, Expires, Max-Age, Secure, HttpOnly, SameSite, Partitioned) and the cookie prefix rules.
- web.dev: Understanding same-site and same-origin: that a site now includes the scheme and how site differs from origin.
- MDN glossary: Site: that a site is the registrable domain, an entry in the Public Suffix List plus the portion just before it.
- MDN: Cross-site request forgery (CSRF): CSRF tokens, Fetch metadata headers such as Sec-Fetch-Site and SameSite as defence in depth.
Frequently asked questions
What is the default if I do not set SameSite?
Current browsers generally treat a missing SameSite attribute as Lax. Because this behaviour has had exceptions and may evolve, it is better to set the attribute explicitly.
Why must SameSite=None be combined with Secure?
Current browsers reject a SameSite=None cookie that lacks Secure. The rule ensures that cookies sent across sites are at least protected from plain HTTP interception.
Is a subdomain a different site for SameSite purposes?
No. Subdomains of the same registrable domain are the same site. Requests between www.example.com and api.example.com are therefore same-site, even though they are cross-origin.
Does SameSite=Strict break links from emails?
It can. The first navigation from another site does not carry the cookie, so the user may appear logged out until they navigate again. Lax avoids this for ordinary link clicks.