Fetch Metadata Request Headers

W3C Working Draft,

More details about this document
This version:
https://www.w3.org/TR/2025/WD-fetch-metadata-20250401/
Latest published version:
https://www.w3.org/TR/fetch-metadata/
Editor's Draft:
https://w3c.github.io/webappsec-fetch-metadata/
Previous Versions:
History:
https://www.w3.org/standards/history/fetch-metadata/
Feedback:
[email protected] with subject line “[fetch-metadata] … message topic …” (archives)
GitHub
Editor:
(Google Inc.)
Participate:
File an issue (open issues)
Tests:
web-platform-tests fetch/sec-metadata/

Abstract

This document defines a set of Fetch metadata request headers that aim to provide servers with enough information to make a priori decisions about whether or not to service a request based on the way it was made, and the context in which it will be used.

Status of this document

This section describes the status of this document at the time of its publication. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/.

This document was published by the Web Application Security Working Group as a Working Draft using the Recommendation track. This document is intended to become a W3C Recommendation.

The (archived) public mailing list [email protected] (see instructions) is preferred for discussion of this specification. When sending e-mail, please put the text “fetch-metadata” in the subject, preferably like this: “[fetch-metadata] …summary of comment…

Publication as a Working Draft does not imply endorsement by W3C and its Members. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by the Web Application Security Working Group.

This document was produced by a group operating under the W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

This document is governed by the 03 November 2023 W3C Process Document.

1. Introduction

Interesting web applications generally end up with a large number of web-exposed endpoints that might reveal sensitive data about a user, or take action on a user’s behalf. Since users' browsers can be easily convinced to make requests to those endpoints, and to include the users' ambient credentials (cookies, privileged position on an intranet, etc), applications need to be very careful about the way those endpoints work in order to avoid abuse.

Being careful turns out to be hard in some cases ("simple" CSRF), and practically impossible in others (cross-site search, timing attacks, etc). The latter category includes timing attacks based on the server-side processing necessary to generate certain responses, and length measurements (both via web-facing timing attacks and passive network attackers).

It would be helpful if servers could make more intelligent decisions about whether or not to respond to a given request based on the way that it’s made in order to mitigate the latter category. For example, it seems pretty unlikely that a "Transfer all my money" endpoint on a bank’s server would expect to be referenced from an img tag, and likewise unlikely that evil.com is going to be making any legitimate requests whatsoever. Ideally, the server could reject these requests a priori rather than delivering them to the application backend.

Here, we describe a mechanims by which user agents can enable this kind of decision-making by adding additional context to outgoing requests. By delivering metadata to a server in a set of fetch metadata headers, we enable applications to quickly reject requests based on testing a set of preconditions. That work can even be lifted up above the application layer (to reverse proxies, CDNs, etc) if desired.

1.1. Examples

A request generated by a picture element would result in a request containing the following HTTP request headers:

Sec-Fetch-Dest: image
Sec-Fetch-Mode: no-cors
Sec-Fetch-Site: cross-site

A top-level navigation from https://example.com to https://example.com/ caused by a user’s click on an in-page link would result in a request containing the following HTTP request header:

Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1

2. Fetch Metadata Headers

The following sections define several fetch metadata headers, each of which exposes an interesting request attribute to a server.

2.1. The Sec-Fetch-Dest HTTP Request Header

The Sec-Fetch-Dest HTTP request header exposes a request’s destination to a server. It is a Structured Field whose value MUST be a token. [RFC9651] Its ABNF is:

Sec-Fetch-Dest = sf-token

Valid Sec-Fetch-Dest values include the set of valid request destinations defined by [Fetch].

In order to support forward-compatibility with as-yet-unknown request types, servers SHOULD ignore this header if it contains an invalid value.

// fetch()’s destination is the empty string:
Sec-Fetch-Dest: empty

// ’s destination is "image"
Sec-Fetch-Dest: image

// new Worker()’s destination is "worker"
Sec-Fetch-Dest: worker

// Top-level navigations' destinations are "document"
Sec-Fetch-Dest: document

//