Safety
Sec-Fetch-Site vs Origin Headers for CSRF Defense
November 13, 2023
Sec-Fetch-Site vs Origin for CSRF defense is two browser-supplied labels, not a token replacement. Sec-Fetch-Site is Fetch Metadata: same-origin, same-site, cross-site, or none (user-initiated, no referrer). Origin is scheme-host-port of the caller on many CORS and POST requests. For cookie-authenticated state changes, reject unexpected Sec-Fetch-Site values (typically allow same-origin, maybe same-site, deny cross-site), still verify Origin against an allowlist, keep SameSite, and keep CSRF tokens. Old clients and some privacy modes omit Fetch Metadata — fail closed or fall back to tokens, do not treat absence as same-origin. RoastMyOpsec does not submit cross-site POSTs and does not score Sec-Fetch-* on your server. It grades Set-Cookie SameSite on the landing response.
The practical difference
Origin answers 'who started this?' Sec-Fetch-Site answers 'how related is that who to this URL?' same-site includes sibling hosts that share a registrable domain. same-origin is stricter. If www and api are different origins on the same site, Sec-Fetch-Site can be same-site while Origin is not your SPA origin.
Referer still leaks paths. Fetch Metadata does not include a path. Do not drop Origin checks because you added Sec-Fetch-Site.
How to choose a policy
State-changing cookie POSTs: require Sec-Fetch-Site of same-origin (or same-site if you truly share cookies across hosts), plus Origin allowlist, plus a CSRF token. Embeds that must POST cross-site with cookies are a SameSite=None design — do not paper over that with Metadata. Navigation GETs that change state should not exist.
| Signal | Granularity | Often missing? | Takeaway |
|---|---|---|---|
| Sec-Fetch-Site | same-origin / same-site / cross-site / none | Older browsers | Reject cross-site cookie POSTs |
| Origin | Exact scheme-host-port | Some GETs; some tools | Allowlist your canonical host |
| CSRF token | Per-session secret | If the form omitted it | Still ship it |
| SameSite Lax/Strict | Cookie attachment | If you set None | Complements Metadata; not a substitute |
What the roast can prove
A roast can show SameSite on Set-Cookie and heuristic token fields in public HTML. It cannot prove your server reads Sec-Fetch-Site. Confirm isolation in the app. Pair with Origin vs Referer and CSRF tokens vs SameSite.
Common mistakes
The first mistake is allowing missing Sec-Fetch-Site as if the client were same-origin.
The second mistake is treating same-site as same-origin when api.example.com should not accept the marketing origin's cookies.
The third mistake is dropping CSRF tokens because Fetch Metadata landed in Chrome.
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
- Does Sec-Fetch-Site replace CSRF tokens?
- No. It is another browser signal. Tokens still help older clients and defense in depth.
- Is same-site safe for all cookie POSTs?
- Only if every host on that site is equally trusted. Prefer same-origin when the app lives on one host.
- Does RoastMyOpsec check Fetch Metadata?
- No. It does not forge cross-site forms or inspect your server's Sec-Fetch-* handling.