RSTR-COOKIE-003 — sameSite: 'none' cookie
Summary
A cookie is configured with sameSite: 'none'. Browsers will send
this cookie on every cross-site request, which means the cookie is
attached to requests originating from third-party pages — the exact
condition that CSRF exploits.
Two failure modes:
- Without
secure: true— modern browsers reject the combination outright; the cookie is silently dropped and the app breaks. - With
secure: true— the cookie is sent cross-site, opening a CSRF surface thatsameSite: 'lax'(the default) would have blocked for state-changing requests.
Severity
Medium. Only set sameSite: 'none' when third-party embedding is
a hard requirement (federated SSO, embedded checkout widgets, etc.).
Languages
JavaScript, TypeScript.
What rastray flags
Cookie options with sameSite: 'none':
res.cookie('sid', token, { sameSite: 'none' }); // ← flagged
app.use(session({
cookie: { sameSite: 'none', secure: true }, // ← flagged
}));
What rastray deliberately does not flag
sameSite: 'lax'(the browser default) orsameSite: 'strict'.- Cookies with no
sameSitefield set explicitly.
How to fix it
Prefer the strictest value that still lets the application work:
res.cookie('sid', token, {
sameSite: 'strict', // safest; cookie never leaves first-party context
secure: true,
httpOnly: true,
});
'lax' is acceptable when top-level cross-site navigations need the
cookie (the common case for OAuth callbacks and login redirects).
If 'none' is genuinely required (third-party iframe scenario), pair
it with secure: true and ensure every state-changing endpoint
has its own anti-CSRF mechanism (synchronizer token, double-submit
cookie). Suppress with an explanatory comment:
// rastray-ignore: RSTR-COOKIE-003 — required for embedded checkout iframe; CSRF
// protected by per-request token in the X-CSRF-Token header
res.cookie('sid', token, { sameSite: 'none', secure: true, httpOnly: true });