The fix, in one snippet
Set-Cookie: session=…; SameSite=Lax; Secure; HttpOnly
# cross-site embeds need: SameSite=None; Secure
Illustrative values. Change the paths, hostnames and options to match your own site before using it.
The sections below explain what is tested, why it matters and the alternatives.
What we test
Scan.now parses the Set-Cookie headers on the response to / and reports each cookie's SameSite value. The check fails at low severity for any cookie with no SameSite attribute, and it also flags SameSite=None without Secure, a combination that Chrome and Firefox reject outright, so the cookie is silently never set. Lax and Strict pass; None; Secure passes with a note, since it is the correct value for a cookie that must work inside cross-site iframes but should not be used for a primary session. Behaviour for a missing attribute differs by browser: Chromium-based browsers have treated it as Lax since Chrome 80 (2020), with a two-minute grace period for top-level POST requests, while Firefox and Safari do not apply that default and still send such cookies on cross-site requests. An explicit attribute removes the difference.
Why it matters
Cross-site request forgery works because the browser attaches your cookies to a request regardless of which page made it. A form on evil.example that auto-submits to https://bank.example/transfer arrives with the victim's session cookie and looks legitimate. SameSite=Lax stops the cookie from being sent on cross-site POSTs, iframe loads and image requests while still sending it when the user follows a normal link to your site, which is why it is the sensible default for a session cookie. Strict also withholds the cookie on link navigation, which is stronger but means a user arriving from an email link sees a logged-out page. SameSite also blunts some clickjacking and cross-site-leak techniques. It is a second layer, not a replacement for anti-CSRF tokens: requests from a sibling subdomain are same-site and still carry the cookie, and GET requests that change state are unaffected. The cookie flags guide covers the trade-offs.
How to fix it
Set SameSite=Lax on session cookies, Strict where the extra friction is acceptable, and None; Secure only for cookies that legitimately need to travel cross-site:
Set-Cookie: session=abc123; Path=/; Secure; HttpOnly; SameSite=Lax
PHP 7.3+ (php.ini):
session.cookie_samesite = Lax
Express with express-session:
app.use(session({ cookie: { sameSite: 'lax', secure: true, httpOnly: true }, /* ... */ }));
Django: SESSION_COOKIE_SAMESITE = 'Lax' (the default) and CSRF_COOKIE_SAMESITE = 'Lax'. ASP.NET Core: options.Cookie.SameSite = SameSiteMode.Lax. Rails sets Lax by default since 6.1. At the proxy, nginx 1.19.3+:
proxy_cookie_flags ~ samesite=lax secure httponly;
Apache: Header edit Set-Cookie ^(.*)$ "$1; SameSite=Lax". For an embedded widget that must keep a cookie inside another site's iframe, use SameSite=None; Secure and treat that cookie as low-trust. Keep your CSRF tokens either way.
Where this fits
Cookie without SameSite attribute is check 3 of 4 that the website vulnerability scanner runs under cookie security, ordered the way they are worth fixing. That ordering is the point: Fixing this one while the check above it still fails buys less than it looks like.
Fix this one first
Above it in the same category sits Cookie without Secure flag (medium), where a cookie is set without the Secure attribute, so the browser will also send it over plain HTTP. An attacker who has that does not need this, so it is the better use of the same hour.
What fixing this still leaves open
Cookie without SameSite attribute closes one route in. The next one down is Cookie name prefixes (__Host- / __Secure-), where session cookies do not use the __Host- or __Secure- name prefixes, so a subdomain, an HTTP origin or a lookalike path could plant a cookie that your site accepts as its own.
Found in the same scan
The website vulnerability scanner reports this alongside checks from other categories that are at least as serious, including Certificate chain and hostname validation, where the certificate presented for this hostname did not validate: The chain does not reach a trusted root, an intermediate is missing, the name does not match, or the certificate is self-signed or expired, and Exposed .env configuration file, where a .env configuration file is served from the web root. A single run of website vulnerability scanner answers all of them at once.
The first few lines
You are a senior web engineer. I ran a security and SEO scanner against my site and it reported the finding below. Fix it properly rather than suppressing the symptom.
Finding: Cookie without SameSite attribute (low severity)
Scanner check id: cookie-samesite
The rest of this prompt names the pages and line numbers we found the problem on, the configuration to change, and the constraints a good answer has to respect. It is free, it just needs an account so the work is not scraped wholesale.
Sign in with GoogleSigning in is free and takes one click. We store your email address and nothing else.