When Chrome 80 changed the SameSite default to Lax in 2020, CSRF defense changed forever. Before, almost every form POST without a CSRF token was vulnerable. After, SameSite=Lax alone blocks most cross-site POSTs. This guide explains the exact differences between Lax, Strict, and None, when Secure is required, what the third-party cookie deprecation means, and what defenses you still need beyond SameSite.
The three SameSite values
None — sent in every context
Set-Cookie: token=abc; SameSite=None; Secure- Cookie is sent on cross-site requests (fetch from another domain, images, iframes).
Secureis required — without HTTPS, browsers ignoreSameSite=None.- Typical use: third-party widgets (chat, comments, ad tracking).
Lax — safe top-level navigation only
Set-Cookie: token=abc; SameSite=Lax- Top-level GET only — cookies are sent when the user clicks a link from another site to yours.
- Cross-site POST, fetch, iframe, and image-style sub-requests do not carry cookies.
- The default in every modern browser since 2020.
- This alone blocks roughly 80% of historical CSRF.
Strict — same site only
Set-Cookie: token=abc; SameSite=Strict- Cookies are sent only on requests originating from the same site.
- Following an external link logs the user out — the cookie doesn't accompany the navigation. Bad UX for users arriving via email or search.
- Reserve for narrow admin/internal pages where cross-site entry isn't needed.
What "same site" actually means — eTLD+1
The "site" in SameSite is not the host — it's eTLD+1 (effective Top-Level Domain + 1):
app.example.comandapi.example.com— same site (eTLD+1 =example.com).example.comandexample.org— different sites.foo.github.ioandbar.github.io— different sites, becausegithub.iois on the Public Suffix List.
The Public Suffix List (PSL) decides. Hosts like github.io and vercel.app are registered there, so their subdomains are cross-site. Split a URL with URL Parser to inspect the eTLD+1 visually.
Don't confuse with CORS origin (scheme + host + port). SameSite is scheme-agnostic and port-agnostic — only eTLD+1 matters.
Lax's POST exception (now mostly gone)
Early in Chrome 80, SameSite=Lax cookies were sent on cross-site POSTs for two minutes after the cookie was set, to accommodate OAuth-style flows. The exception was removed by 2021 — OAuth now uses explicit SameSite=None; Secure or a GET-based redirect.
Third-party cookie deprecation (2024–2025)
Chrome began rolling out third-party cookie blocking in January 2024 (1% → 100%). Safari and Firefox have blocked by default for years.
Impact:
- Ad tracking — the biggest hit. Privacy Sandbox (Topics API, etc.) is the proposed replacement.
- SSO / federated identity — Google Sign-In and friends. FedCM (Federated Credential Management) is the alternative.
- Embedded widgets — Disqus comments, Stripe Checkout, etc. need
SameSite=Nonewith explicit user consent, or a redirect flow on their own domain.
For new sites in 2026 — don't depend on third-party cookies. Use redirect flows that land on your own domain.
Other cookie attributes
Secure
Sent only on HTTPS. Required alongside SameSite=None.
HttpOnly
Inaccessible to document.cookie. Closes the "one XSS leaks every token" hole. Auth cookies must be HttpOnly.
__Host- / __Secure- prefixes
__Secure-name— only settable on a response withSecure.__Host-name— same plusPath=/and noDomainattribute. Pinned to exactly one host.
The safest auth cookie:
Set-Cookie: __Host-session=abc; Path=/; Secure; HttpOnly; SameSite=LaxDrop a Set-Cookie header into Cookie Parser to see exactly how each attribute parses.
Is SameSite enough by itself?
On modern browsers (2020+) with Lax as the default, 99% of cross-site POST/fetch is automatically blocked. But SameSite does not stop every CSRF:
- Same-site XSS — an XSS on your own site bypasses SameSite entirely. Pair with CSP.
- Subdomain takeover — if
blog.example.comis hijacked, it can useexample.com's SameSite cookies. - Legacy browsers — old Android and IE don't support SameSite. Low share, but non-zero.
- Intentional
SameSite=None— for cross-site integrations, SameSite is off by design.
SameSite is the first line. Combine with:
- CSRF tokens on state-changing requests — hidden input in forms or a custom header. Server validates.
- Origin / Referer check — lighter. Verify the
Originheader matches your domain on POSTs. - Double-submit cookie pattern — the cookie value and a header value must match. JS reads the cookie and sets the header.
Real-world pattern — auth cookie + API
# 1. Login response — safest form
Set-Cookie: __Host-session=eyJhbGc...;
Path=/;
Secure;
HttpOnly;
SameSite=Lax;
Max-Age=86400
# 2. Subsequent API calls send the cookie automatically
GET /api/me
Cookie: __Host-session=eyJhbGc...
# 3. Attempted cross-site fetch (malicious site)
fetch("https://example.com/api/transfer", {
method: "POST",
credentials: "include"
});
# → SameSite=Lax blocks the cookie on POST → 401A same-site SPA calls the API with credentials: include; cross-site is blocked automatically.
Common pitfalls
1. SameSite=None without Secure
The browser ignores it. The cookie never sets. A common debugging dead-end.
2. SameSite=None on dev (http localhost)
Won't work without Secure. Dev uses SameSite=Lax or omits it. Or temporarily flip the Chrome flag at chrome://flags.
3. Removing CSRF tokens because of SameSite
Same-site XSS defeats SameSite. Keep tokens for high-stakes actions (payments, account changes).
4. Applying Strict broadly
Users arriving via an external link look logged out. SEO and email traffic suffer. Strict only fits a narrow set of contexts.
5. Misunderstanding eTLD+1
api.example.com and app.example.com are the same site — cookies from one are sent to the other. Don't assume they're isolated security contexts.
6. Relying on third-party cookies in 2026
Chrome's deprecation rolls forward. Embedded widgets need a redirect flow; SSO needs FedCM.
7. Reading auth cookies from document.cookie
HttpOnly stops that — by design. Check session status via a separate API like /api/me.
Summary
- Modern browsers default to
SameSite=Lax. Cross-site POST/fetch is blocked automatically. None+Securefor cross-site integrations — increasingly deprecated.Strictbreaks entry-from-elsewhere UX — narrow admin pages only.- Safest auth cookie =
__Host-name; Path=/; Secure; HttpOnly; SameSite=Lax. - SameSite is the first defense. Pair with CSP + CSRF tokens + Origin checks for everything important.
- Third-party cookies are deprecated in 2024–2025. Design new systems for first-party only.