Security teams often need a cheap way to reject cross-site requests before a request reaches application code. The Sec-Fetch-Site request header provides one signal for that decision. It describes the relationship between the request initiator's origin and the requested resource's origin. A browser labels a request from another site as cross-site, while a same-origin request receives a different value.
That sounds like a replacement for a CSRF token. It is not. Sec-Fetch-Site is useful defense in depth because it is generated by the browser as part of Fetch Metadata. It cannot establish who the user is, whether a session is valid, or whether a state-changing request is appropriate. A server that trusts the header without considering its clients can also break automation, mobile applications, and requests that do not originate from a browser.
What the browser sends
The Fetch metadata family includes Sec-Fetch-Site, Sec-Fetch-Mode, Sec-Fetch-Dest, and Sec-Fetch-User. The site header has values such as same-origin, same-site, cross-site, and none. The none value covers requests without an initiating site, including a URL typed into the address bar or opened from a bookmark.
MDN describes the header as information the server can use to accept or reject requests. It is not an instruction that a browser obeys. The server must make the policy decision and should fail safely when a request does not match the expected pattern.
A typical API policy allows same-origin for state-changing endpoints and rejects cross-site. That rule can reduce exposure to simple HTML form submissions and some cross-origin script requests. It does not eliminate the need for an unpredictable CSRF token, SameSite cookies, Origin validation, and server-side authorization.
The header can be absent
Older browsers, non-browser clients, HTTP libraries, and some intermediary requests may omit Fetch metadata entirely. A policy that rejects every request without Sec-Fetch-Site may protect a browser-only application while blocking a mobile client or a partner integration. A policy that allows every missing header gives an attacker a trivial bypass if the attacker can send a request outside the browser.
The right response depends on the interface. A browser-facing endpoint can require the header and reject absent values. A public API should authenticate its clients and use the header as an additional signal, not as the primary control. If the API accepts both browser and machine clients, the policy should be explicit about which routes expect which client model.
Do not assume that a proxy will preserve the original value through every rewrite or gateway. Record the header at the edge and inside the application during testing. A reverse proxy may add its own metadata, strip a header during debugging, or route a request through a different hostname. The application should know which layer is authoritative.
same-site is not same-origin
same-site can include requests between related hostnames, while same-origin requires scheme, host, and port to match. A policy that treats both values as equivalent can widen access across subdomains or from HTTP to HTTPS under the same registrable site. That may be acceptable for a carefully bounded application, but it should be a deliberate decision.
The distinction is particularly important for administrative routes. A shared authentication service may live on a sibling hostname, and a cross-origin request to the admin API could still be same-site. An allowlist that only rejects cross-site may permit it. Use an explicit route-specific policy rather than a global rule whose meaning changes as hostnames are added.
Also consider navigation requests. Clicking a link from an email or another site can produce a cross-site request that the user intended. A blanket rejection on GET routes may break normal navigation. State-changing operations should use POST or another appropriate method, be protected by CSRF tokens, and require authorization. The header alone is too coarse to decide user intent.
Logging and failure behavior
Log the observed values, request method, route, authentication state, and whether a CSRF token was present. Do not log cookies or bearer tokens. A rejected request can reveal a broken integration or an attempted cross-site request. The same value should not automatically create a high-severity alert without context.
Choose the failure behavior by route. For a browser-only privileged action, default deny may be appropriate. For a public data endpoint, returning a normal error or requiring authentication is safer than treating the header as an authorization claim. The application should not fall back to the user's claims from an untrusted header or a client-provided origin value.
Tests should cover the absence of the header, each expected value, an unknown value, a cross-site POST, a same-site sibling origin, and a direct address-bar navigation. Run the tests through the real edge proxy, not only against the application server.
The useful role
Sec-Fetch-Site is a low-cost filter that can keep many cross-site requests away from sensitive handlers. It works best as one layer in a stack that already includes SameSite cookies, CSRF tokens, exact Origin checks, authentication, and authorization. It does not replace any of those controls.
The implementation is mature when the application can explain which routes accept which client types, what happens when the header is missing, and why a same-site request is or is not treated as a cross-origin risk. That is a narrower and more useful goal than claiming the header solves CSRF.