Safety
SameSite=Strict vs Lax for Login Cookies
August 29, 2025
SameSite=Strict vs Lax for login cookies is when the browser attaches that cookie on a request that started on another site: Lax still sends it on top-level GET navigations, while Strict withholds it on all cross-site requests so an inbound email or ads click often looks logged out. Most public logins should ship Lax with Secure and HttpOnly; reserve Strict for high-sensitivity apps that can live without the cookie on that first hop. RoastMyOpsec checks that SameSite is present on session-like landing cookies — it does not fail Lax, does not prefer Strict, and does not POST CSRF proofs.
The practical difference
Lax is the modern default story for first-party sessions: cross-site subresource and classic cross-site POST usually omit the cookie; a top-level GET to your site still sends it so 'open this link' still sees the session. Strict is a tighter belt: the cookie stays on same-site requests only, which is why return-from-IdP, magic links, and some checkout success URLs look anonymous until a second same-site click.
SameSite=None is a different product (cross-site embeds) and requires Secure. Do not mark the login cookie None because a widget asked. Lax is not a complete CSRF program for every state-changing POST; keep tokens or Origin checks on those forms.
How to choose based on what you shipped
Brochure plus WordPress login, SaaS marketing site with an app on the same registrable domain, and most OAuth returns: SameSite=Lax on the session name. Banking-style or internal admin where users always type the URL: Strict can win after you test email links and payment redirects.
If Strict breaks a real top-level return, do not 'fix' it with None on the same name. Use Lax, or a short bounce on your own origin that then navigates same-site.
| Option | When it wins | Watch-out | Takeaway |
|---|---|---|---|
| SameSite=Lax | Public login, email links, ads-to-app hops, most OAuth returns | Not a full CSRF substitute for every POST | Default for session cookies on marketing-plus-app origins |
| SameSite=Strict | High-sensitivity session, users land same-site, no inbound cookie needed | First request from another site looks logged out | Ship only after testing payment and magic-link returns |
| SameSite=None; Secure | A dedicated embed or SSO cookie that must travel cross-site | The main session name wearing None | Different cookie, not a Strict/Lax compromise |
| Missing SameSite | Never for new auth cookies | Browser defaults differ and change | Set Lax or Strict on purpose |
When SameSite=Strict still wins
Strict still wins when the login cookie must never ride an inbound cross-site GET — admin consoles, high-value sessions, users who bookmark the app. Pair it with a same-site interstitial if you still send mail links: the mail hits a cookieless landing, then a same-site continue sets the session in view.
Lax still wins for almost every public brand login. Treating Strict as a roast requirement is a misread: the free cookie check wants SameSite present on session-like names, not a particular value.
Common mistakes
The first mistake is SameSite=Strict on the session and then SameSite=None 'so Google ads work' on the same name.
The second mistake is Lax as the only CSRF control on JSON APIs that accept cross-site POSTs from old browsers.
The third mistake is assuming a homepage roast saw the login cookie when only a marketing pixel was set.
What a URL roast can prove
A RoastMyOpsec URL roast reads the primary response: CSP quality signals, HSTS, framing, Referrer-Policy, nosniff, Permissions-Policy, HTTPS scheme, session-like cookie flags, sensitive paths, and public JS secrets. For cookies it checks Secure, HttpOnly, and SameSite on session-shaped names — including SameSite=None without Secure. It does not score Strict versus Lax as a standalone F, does not score cookie Max-Age versus session, and does not log in. Missing SameSite is the cookie finding; picking Lax is not. No exploit payloads.
Free audit the URL you own
RoastMyOpsec is a defensive public-surface roast: headers, cookies, sensitive paths, and more — no exploit payloads. Start with the free audit, then open the vault if the blurred findings look expensive.
Free audit nowFAQ
- Should my login cookie be SameSite=Strict or Lax?
- Lax is the usual public-login default. Use Strict only when you can live without the cookie on inbound cross-site top-level GETs and you have tested mail and payment returns.
- Does RoastMyOpsec require SameSite=Strict?
- No. It checks that SameSite is set on session-like landing cookies. Lax satisfies that check. It does not send CSRF proofs.
- Is Lax enough without CSRF tokens?
- Lax cuts a class of cross-site POSTs. Keep CSRF tokens or strict Origin checks on state-changing forms, especially if you still support older clients.