Headers
SameSite + Secure cookies: the two attributes every session cookie needs.
Published 2026-05-03 · Last updated 2026-05-03 · Vantyris editorial
Every session cookie your site sets needs two attributes set correctly: `Secure` (only sent over HTTPS) and `SameSite` (only sent on first-party requests). Without them, a session cookie can be stolen by an attacker on the same network as your visitor, or used by a malicious third-party site to impersonate your user in a cross-site request forgery (CSRF) attack. Modern browsers default to `SameSite=Lax` if you don't set it, which helps, but the explicit attribute lets you choose the right setting per cookie type and gives you a clear audit trail.
What this means for your business
- Without `Secure`, your session cookie can be sent over a plain HTTP connection (if any subdomain still serves HTTP). Anyone on the visitor's network can read it and replay it to log in as the visitor.
- Without `SameSite`, a malicious site that the visitor opens in another tab can trigger a request to your site (via an image tag, a form submission, or a fetch call), and the browser attaches your session cookie automatically. The malicious site can effectively perform any action your visitor could.
- `SameSite=Lax` (the modern default) attaches the cookie on top-level navigations (clicking a link) but not on cross-site embedded requests (iframes, forms). `SameSite=Strict` attaches only on same-site navigations. `SameSite=None` is required for cookies sent in third-party contexts (e.g., embedded widgets); it requires `Secure` too.
How to fix
Audit every Set-Cookie response from your application. Add `Secure; SameSite=Lax` (or `Strict` for session cookies) to each one. For OAuth + payment-redirect flows that need cross-site cookies, use `SameSite=None; Secure` explicitly.
- Audit your current Set-Cookie responses. Open Chrome DevTools → Application → Cookies. List every cookie your site sets. Click each one and check the Secure + SameSite columns. Empty values mean the browser uses defaults; explicit values mean you've thought about it.
- Update your framework's cookie defaults. Node.js Express: `app.use(session({ cookie: { secure: true, sameSite: 'lax' } }))`. Rails: `Rails.application.config.session_store :cookie_store, secure: true, same_site: :lax`. Next.js (cookies via headers): pass `secure: true, sameSite: 'lax'` to every `cookies().set(...)` call.
- Handle the cross-site exceptions explicitly. For cookies that genuinely need cross-site (third-party widget consent, embedded checkout flows), set `SameSite=None; Secure`. Browsers reject `None` without `Secure`. Don't use `None` unless you've thought about it; the default should be `Lax`.
- Verify in DevTools after deploy. Reload your site, re-check Application → Cookies. Each cookie should now show the explicit values. If any are missing, the cookie is being set somewhere you didn't update (often a third-party library).
Owner: Your developer. · Time: 30-60 minutes for a typical app with 3-5 cookies.
Common gotchas
- `Secure` requires HTTPS. If your local dev environment is HTTP, the Secure flag prevents the cookie from being set during development. Most frameworks have an `is_production` toggle that scopes the flag to production only.
- `SameSite=Strict` blocks the cookie on the initial click-from-email or click-from-social-share. Users land on your site logged out. Most sites prefer `SameSite=Lax` for session cookies and reserve `Strict` for high-risk flows (e.g., the admin panel).
- Older browsers (pre-2017) don't understand SameSite and treat it as missing. Negligible market share today; ignore.
- Some payment SDKs (Stripe Checkout, embedded PayPal) require third-party cookies and break under `SameSite=Lax`. Use `SameSite=None; Secure` for those specific cookies, not for all of them.
How to verify the fix
Vantyris's verified scan checks every Set-Cookie response and flags ones missing Secure or SameSite. Or in DevTools, the Application → Cookies tab shows the attributes explicitly.
Cyber Essentials alignment
This finding informs the following UK NCSC Cyber Essentials control areas:
- A2. Secure configuration — devices and services hardened against the inherent default vulnerabilities.
Vantyris is not a CE certifying body. The mapping above is informational.
Common follow-up questions
Do these attributes prevent XSS attacks?
Partly. They prevent COOKIE THEFT via XSS if you also set `HttpOnly` (which blocks JavaScript reading the cookie). XSS that doesn't need to read the cookie (e.g., performing actions while the user is logged in) is still possible. CSP is the main XSS defence.
What if I use a third-party authentication provider?
Their cookies have their own flags. You can't control those; you're trusting the provider. Big providers (Google, Auth0, Clerk, Stripe) set them correctly. Audit them yourself by checking DevTools after a login flow.
Does SameSite=Lax break anything I care about?
Almost never. The behavioural difference between None and Lax is whether the cookie is sent on cross-site requests from iframes / forms / fetches. Modern apps rarely depend on this; if yours does, you'll notice during testing.
References
Related explainers
- Content Security Policy: the header that stops most XSS attacks dead.
- HSTS: the security header that locks HTTPS on for good.
Want Vantyris to scan your domain for this and 80 other findings?
Free teaser scan, no card. Verified scan from €10 with the full workspace around it: workflow, score trend, three PDF layouts, share links, monitoring.
Vantyris editorial team · methodology v1.0.0