Fetch Metadata Headers Gate Cross-Site Requests
A web server often receives enough HTTP information to route a request but not enough to tell what browser context produced it. A GET might be a top-level navigation, an image load, or a JavaScript fetch. A POST might come from the application’s own page or from a form hosted on another site.
Fetch Metadata adds browser-generated request headers that describe that context. Sec-Fetch-Site reports the relationship between the initiator and target, while Sec-Fetch-Mode, Sec-Fetch-Dest, and in some cases Sec-Fetch-User describe the request mode, destination, and user activation. A server can use those signals to reject request shapes that an endpoint has no reason to accept.
The headers are policy inputs, not an authorization system. They do not identify a user, validate a CSRF token, or make a sensitive operation safe by themselves.
Sec-Fetch-Site marks the site relationship
For many isolation policies, Sec-Fetch-Site is the first useful signal. Common values are:
same-origin
same-site
cross-site
nonesame-origin means the initiator and target share the same origin. same-site permits a different origin within the same site. cross-site marks a request initiated from another site. none is used for requests without a site initiator, including some direct user actions such as entering a URL or opening a bookmark.
That distinction lets a server express a narrow rule. A state-changing application endpoint that is intended only for its own origin can reject cross-site requests before application logic performs the operation.
Sec-Fetch-Site: same-origin --> candidate for normal processing
Sec-Fetch-Site: cross-site --> reject when endpoint policy forbids itSame-site is not equivalent to same-origin. Applications that place mutually untrusted tenants or user-controlled content on sibling subdomains should not automatically treat every same-site request as trusted. The policy has to match the actual trust boundary.
Mode and destination add request shape
Site relationship alone does not describe what the browser is trying to do. Sec-Fetch-Mode and Sec-Fetch-Dest add useful context.
A top-level document navigation commonly carries a mode such as navigate and a destination of document. An image load has a destination of image. A JavaScript fetch() request commonly has destination empty, with its mode determined by the fetch configuration and origin relationship.
That enables endpoint-specific decisions. A public page may intentionally accept cross-site top-level GET navigations while an authenticated JSON endpoint may have no legitimate cross-site image, script, or no-CORS use.
A simplified policy can look like this:
if Sec-Fetch-Site is same-origin:
allow normal processing
else if request is a safe top-level navigation:
allow public navigation
else:
rejectReal applications need explicit exceptions for resources designed for embedding, cross-origin APIs, webhooks, federated flows, and other documented entry points. A global rule copied across every route can break valid traffic or create broad exceptions that erase the benefit.
Browser-controlled headers raise the cost of cross-site forgery
Fetch Metadata headers use the Sec- prefix and are forbidden request headers in browser JavaScript. Front-end code cannot freely set them to arbitrary values through fetch().
This property is useful at the server boundary. An attacker page can cause several classes of browser request, but it cannot simply label a cross-site request as same-origin from JavaScript. The browser supplies the metadata according to the request context.
The server still has to apply a policy. Receiving Sec-Fetch-Site: cross-site does not automatically block anything. Fetch Metadata is descriptive; enforcement belongs to the application, reverse proxy, gateway, or another trusted server-side layer.
Non-browser clients are a separate case. Command-line tools, mobile applications, service integrations, and older user agents may omit these headers. A deployment must decide what omission means for each endpoint instead of assuming every request carries browser metadata.
Missing headers need an explicit compatibility rule
A strict policy that rejects every request without Fetch Metadata can disrupt legitimate clients. A permissive policy that treats absence as trusted can leave legacy traffic outside the isolation check.
Migration therefore benefits from a defined fallback. For browser-facing state-changing routes, the server can combine Fetch Metadata with existing CSRF controls and origin checks. For machine APIs, authentication and protocol-specific authorization remain the primary boundary.
The key is to avoid interpreting absence as evidence of same-origin context. Missing metadata is simply missing metadata.
During rollout, telemetry can record the route, method, relevant Fetch Metadata values, and policy decision. That makes compatibility gaps visible before enforcement is widened. Logs should avoid unnecessary sensitive request data.
Fetch Metadata complements CSRF tokens and SameSite cookies
A CSRF token proves possession of a value that an attacker site should not have. SameSite cookie attributes influence when browsers attach cookies to cross-site requests. Fetch Metadata tells the server about request context. These controls act at different points.
For a sensitive cookie-authenticated endpoint, a layered design can include:
session cookie policy
+
CSRF token validation
+
Origin or Referer validation where suitable
+
Fetch Metadata isolation policyFetch Metadata can reject obviously incompatible cross-site traffic early, before deeper request processing. It should not silently replace an established CSRF mechanism unless the application’s browser support, client population, endpoint semantics, and fallback behavior have been evaluated as one system.
The same caution applies to CORS. CORS controls whether browser JavaScript can read certain cross-origin responses and, for some requests, whether a preflight authorizes the operation. It is not a general substitute for server-side request authorization. Fetch Metadata provides a different signal and can be enforced even for request forms that do not depend on readable responses.
Public resources need deliberate exceptions
Some resources are meant to be used from other sites. Images may be embedded, scripts may be distributed through a public endpoint, and an API may intentionally support selected cross-origin callers.
An isolation policy should classify those routes instead of adding a blanket cross-site allowance. For example:
/public-images/* allow expected image loads
/public-docs/* allow top-level navigation
/api/private/* require application API policy
/account/* reject incompatible cross-site requestsSec-Fetch-Dest can help distinguish a document request from an image or script request, but it is still a contextual signal. The server must decide whether that destination is appropriate for the resource.
Caching also deserves attention when response behavior varies by Fetch Metadata values. Shared caches need a configuration that does not reuse a response across request contexts in a way that violates the server’s policy. Where response selection depends on these headers, cache keys or Vary handling must remain aligned with that decision.
Apply the policy before sensitive work
The isolation check is most useful near the request boundary. Rejecting an incompatible request after a database transaction, expensive body parsing, or a state change has already started is too late.
A practical sequence is:
request arrives
|
validate request context
|
reject incompatible cross-site shape
|
authenticate and authorize
|
validate CSRF and application inputs
|
perform operationThe exact order can vary with framework and endpoint requirements, but no metadata check should be mistaken for user authorization. A same-origin request can still come from a compromised page, malicious extension, XSS path, or authenticated user without permission for the requested object.
Fetch Metadata narrows one attack surface: browser requests whose cross-site context does not fit the resource being requested. Its value comes from keeping that boundary precise, documenting exceptions, and retaining the controls that protect identity, object access, and state changes.
References
- MDN, Fetch metadata: https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Fetch_metadata
- MDN, Sec-Fetch-Site header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Sec-Fetch-Site