Sec-Fetch-Dest Header: Verifying Request Context
This article explores how the Sec-Fetch-Dest header
enables backend servers to determine the exact technical context in
which an incoming HTTP request was initiated. It explains the mechanics
of Fetch Metadata request headers, details how backends can identify the
intended destination of a requested resource (such as a script, image,
or document), and demonstrates how verifying this context prevents
common web vulnerabilities like Cross-Site Script Inclusion (XSSI) and
unauthorized resource embedding.
What is the Sec-Fetch-Dest Header?
The Sec-Fetch-Dest header is part of the W3C Fetch
Metadata Request Headers specification. It is automatically attached by
modern web browsers to outgoing HTTP requests to indicate the
destination of the requested data—specifically, the HTML element or API
that initiated the call.
Because it belongs to the Sec- prefix family, the
browser treats it as a forbidden header name. JavaScript running on the
client side cannot modify or spoof this header using APIs like
fetch() or XMLHttpRequest. This guarantees to
the backend server that the value truthfully reflects the browser's
execution context.
Common Values and Their Contexts
The value of Sec-Fetch-Dest changes depending on how the
browser intends to consume the response:
document: The request is for a top-level HTML navigation (e.g., a user typing a URL or clicking a standard link).iframe/frame: The request is intended to load within an embedded frame.script: The resource is being fetched to execute as JavaScript via a<script>tag.image: The resource is loaded as an image (via<img>, CSSbackground-image, or SVG).style: The resource is an external CSS stylesheet (<link rel="stylesheet">).empty: The request was initiated programmatically without a dedicated visual destination, commonly throughfetch()orXMLHttpRequest.
How Backends Verify Request Context
Backend servers verify request context by comparing the declared
destination in the Sec-Fetch-Dest header against the
expected data type of the requested endpoint.
1. Preventing Cross-Site Script Inclusion (XSSI)
Sensitive JSON APIs containing user-specific data are often
vulnerable to XSSI attacks, where a malicious site uses a
<script src="https://api.example.com/user-data"> tag
to read data via dynamic script execution.
A backend server can inspect Sec-Fetch-Dest on endpoints
that return JSON. If the incoming request contains
Sec-Fetch-Dest: script, the server recognizes that the
browser intends to execute the payload as executable code rather than
consuming it via standard API calls. The server can immediately reject
the request with an HTTP 403 Forbidden status.
2. Blocking Malicious Resource Embedding
Attackers may embed internal assets, administrative interfaces, or
sensitive files into unauthorized contexts on third-party sites (e.g.,
loading an internal dashboard inside an <iframe> or
an administrative export endpoint within an <img>
tag).
By evaluating Sec-Fetch-Dest, a server can enforce
structural rules:
- An API endpoint that modifies state (like updating account details)
should never arrive with a destination of
image,style, orscript. - A sensitive HTML document meant only for direct user interaction
should have a destination of
document, rejecting requests marked asiframe.
3. Enforcing Resource Isolation Policies
Backend middleware can implement comprehensive isolation rules
combining Sec-Fetch-Dest with other Fetch Metadata headers,
such as Sec-Fetch-Site.
For instance, a backend policy can allow top-level navigation
(Sec-Fetch-Dest: document) from external sites to let users
follow inbound links, while strictly blocking any cross-site request
where Sec-Fetch-Dest is set to empty,
script, or image. This provides
defense-in-depth against Cross-Site Request Forgery (CSRF) without
relying exclusively on tokens.
Backend Implementation Considerations
When verifying Sec-Fetch-Dest on the server:
- Handle Missing Headers Gracefully: Older browsers or non-browser clients (such as mobile applications or server-to-server calls) do not send Fetch Metadata headers. Backend logic should decide whether to allow requests lacking the header based on the endpoint's threat profile.
- Pair with Content-Type Validation:
Sec-Fetch-Desttells the server what the browser wants to do with the data, but the server must still set the appropriateContent-TypeandX-Content-Type-Options: nosniffheaders in its response to prevent MIME-confusion attacks on the client side.