Safety
CSRF Tokens vs SameSite for State-Changing Forms
April 23, 2023
CSRF tokens vs SameSite is a pairing, not an either-or contest. SameSite on the session cookie reduces how often a foreign site can attach credentials to a request. Anti-CSRF tokens (or Fetch metadata / Origin checks) still belong on state-changing forms because SameSite=Lax allows some top-level GETs, cookies can be SameSite=None for embeds, and not every client is a modern browser. RoastMyOpsec's vault CSRF check is a heuristic on landing HTML — form tags and token-ish field names — not a proof that your server validates anything.
The practical difference
SameSite is a cookie attribute. It changes when the browser includes the cookie on cross-site requests. It does nothing if the action does not need that cookie, or if the cookie is None.
A CSRF token is an unguessable value bound to the session that the server demands on POST/PUT/DELETE. Origin and Referer checks are a complementary server rule: reject state changes whose Origin is not you.
How to choose based on the form
Read-only search GET forms are usually not CSRF-critical. Password change, transfer, delete, and email-update POSTs are. Cookie-based apps should set SameSite=Lax or Strict on the session cookie and still require a token or Origin check on those POSTs.
| Control | Stops | Does not stop | Takeaway |
|---|---|---|---|
| SameSite=Lax | Many cross-site POSTs with cookies | Some cross-site top-level GETs; None cookies | Necessary default, not sufficient alone |
| SameSite=Strict | More inbound cookie riding | Logged-out CSRF of unauthenticated actions | Best for consoles; worse for inbound links |
| Synchronizer / double-submit token | Forged POSTs that lack the secret | XSS that can read the token | Still need HttpOnly sessions and CSP |
| Origin / Referer check | Cross-site POSTs with a clear Origin | Missing Origin edge cases | Cheap extra belt on the server |
When SameSite-only fails
SPA frameworks that put mutations on GET, or that use SameSite=None for a widget, re-open the old problem. Tokens and Origin checks are how you keep those designs honest.
If there are no forms on the landing page, a public scan may look clean. Confirm login and settings routes on a host you own.
Common mistakes
The first mistake is SameSite=Lax on the cookie and no server check on POST.
The second mistake is a CSRF token in the page that the API never validates.
The third mistake is protecting /login and leaving /api/delete wide open.
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
- Is SameSite enough to stop CSRF?
- It is a strong reduction for cookie-based sites on modern browsers. It is not enough by itself for every cookie mode, every method, or every client. Keep tokens or Origin checks on state changes.
- Do JSON APIs need CSRF tokens?
- Cookie-authenticated JSON APIs still need a CSRF strategy (token, custom header that CORS would not send from a foreign site, or SameSite plus Origin). Bearer tokens in Authorization are a different model.
- How does RoastMyOpsec check CSRF?
- It parses public landing HTML for forms and common token field names. Heuristic only — no forged submissions.