RoastMyOpsec

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.

SignalGranularityOften missing?Takeaway
Sec-Fetch-Sitesame-origin / same-site / cross-site / noneOlder browsersReject cross-site cookie POSTs
OriginExact scheme-host-portSome GETs; some toolsAllowlist your canonical host
CSRF tokenPer-session secretIf the form omitted itStill ship it
SameSite Lax/StrictCookie attachmentIf you set NoneComplements 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 now

FAQ

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.

Sources

Related guides