Many web attacks reach a state-changing endpoint through a request shape the application never intended. A page may expect a JSON POST from its own JavaScript, then accept the same action from a cross-site form, an image load, or a top-level navigation. Fetch Metadata headers give the server a way to inspect that request context before the business logic runs.
The specification defines headers that describe how a request was initiated. Sec-Fetch-Site identifies the relationship between the initiator and the target. Sec-Fetch-Mode describes the request mode, and Sec-Fetch-Dest identifies the expected destination. Sec-Fetch-User indicates whether a navigation was triggered by user activation. Browsers add these headers so a server can make an early decision about whether the request fits the endpoint's contract.
The useful boundary
Fetch Metadata is most valuable at endpoints with a narrow expected context. An internal API that should only receive same-origin fetch calls can reject a cross-site navigation before authentication or business logic. A browser-only download endpoint can require a document or image destination. A session-changing GET can be rejected because state changes should not depend on a navigation side effect.
The headers do not replace authentication or CSRF tokens. An attacker who can make a request from the same origin, abuse an open redirect, or reach the endpoint outside a browser still needs to be handled by the normal authorization model. The headers reduce the number of valid request shapes, which makes the remaining checks easier to reason about.
A conservative policy
Start in monitoring mode. Record the observed Sec-Fetch-* values by endpoint and method, then compare them with the intended callers. A same-origin application programming interface may legitimately see same-origin, cors, navigate, or no-cors depending on how it is used. Do not assume that every request lacking a header is malicious. Older browsers, command-line clients, health checks, and some middleware paths may omit the headers.
For a state-changing API, an explicit policy can require a JSON-oriented request and a same-origin relationship. For a sensitive navigation endpoint, require a top-level navigation with user activation when that is the real workflow. Return a clear denial and log the relevant headers without logging credentials or request bodies.
Example policy logic, expressed as pseudocode rather than a framework-specific implementation:
if method changes state:
reject if Sec-Fetch-Site is cross-site
reject if Sec-Fetch-Mode is navigate and endpoint expects fetch
reject if Sec-Fetch-Dest is not in the endpoint's allowed set
The exact values should come from observed traffic, not from a generic blocklist.
Failure modes and deployment concerns
Proxy chains can strip or rewrite request headers. Test the policy after TLS termination, ingress routing, and application middleware. If a reverse proxy adds a second set of headers or forwards a client-supplied value, the application may make a decision from the wrong source. Browser-set Fetch Metadata headers are intended to be handled by the browser, but non-browser clients can still send arbitrary headers. That is another reason to keep authorization server-side.
Caching also deserves review. A response that varies on Sec-Fetch-Site must not be shared across request contexts unless the cache key includes that variation. A denial response should not be cached for a legitimate navigation. Use the appropriate Vary behavior and test through the actual CDN or reverse proxy.
What to monitor
Track denials by endpoint, source relationship, and destination. A sudden rise in cross-site denies can indicate a broken integration, a new frontend deployment, or an attack campaign. A sudden drop in requests that carry the headers can indicate a proxy change or a client population outside the browser. Keep a separate audit trail for requests that reach the business logic after the context check passes.
Fetch Metadata is useful because it gives the server a low-cost way to distinguish request intent from request authenticity. It should be one part of a layered endpoint contract: authenticated identity, authorization, CSRF protection where applicable, input validation, and an explicit policy for how the endpoint may be called.
References
W3C Web Application Security Working Group, Fetch Metadata Request Headers