RFC 8942
HTTP Client Hints
RFC 8942: HTTP Client Hints β¨
- Stream: Internet Engineering Task Force (IETF) πΈ
- Authors: I. Grigorik and Y. Weiss, both from Google π
- Category: Experimental π§ͺ
- Date: February 2021 π
- ISSN: 2070-1721
- Obsoletes / Updates: The header doesn't list any RFCs this one obsoletes or updates, so no drama here π
Abstract πΈ
Okay so HTTP has this thing called proactive content negotiation, where the server picks the best response for you based on what your user agent (basically your browser) tells it through request headers. Cute! π But in practice, user agents are kinda hesitant to actually send those headers, because nobody's sure they'll get used, and sending them hurts both performance and privacy. π
This doc defines an Accept-CH response header that servers can use to say "hey, I actually use these request headers for content negotiation." It also gives you some guidelines for making headers like that, which are colloquially known as "Client Hints." π
Status of This Memo π
This document is not an Internet Standards Track specification; it is published for examination, experimental implementation, and evaluation. π§ͺ
This document defines an Experimental Protocol for the Internet community. It's a product of the IETF and represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). Not every document approved by the IESG is a candidate for any level of Internet Standard, so see Section 2 of RFC 7841. π
Info about the current status of this document, any errata, and how to give feedback on it can be found at https://www.rfc-editor.org/info/rfc8942. π¦
Copyright Notice βοΈ
Copyright (c) 2021 IETF Trust and the persons identified as the document authors. All rights reserved. β¨
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, because they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions, and they're provided without warranty as described in the Simplified BSD License. π«Ά
Table of Contents ποΈ
1. Introduction
1.1. Notational Conventions
2. Client Hints Request Header Fields
2.1. Sending Client Hints
2.2. Server Processing of Client Hints
3. Advertising Server Support
3.1. The Accept-CH Response Header Field
3.2. Interaction with Caches
4. Security Considerations
4.1. Information Exposure
4.2. Deployment and Security Risks
4.3. Abuse Detection
5. Cost of Sending Hints
6. IANA Considerations
6.1. Accept-CH
7. References
7.1. Normative References
7.2. Informative References
Acknowledgements
Authors' Addresses
1. Introduction β¨
There are thousands of different devices accessing the web, and each one has its own device capabilities and preference info. π± These capabilities include hardware and software characteristics, plus dynamic user and user agent preferences. Historically, if an app wanted the server to optimize content delivery and user experience based on all that, it had to rely on passive identification. For example, it could match the User-Agent header field (Section 5.5.3 of [RFC7231]) against an established database of user agent signatures. Or it used HTTP cookies [RFC6265] and URL parameters, or some mix of these and similar mechanisms, to do ad hoc content negotiation. π΅οΈββοΈ
Those techniques are expensive to set up and maintain, and they're not portable across apps and servers. They also make it hard for both the user agent and the server to figure out which data is required and in use during the negotiation:
- User agent detection can't reliably identify all static variables, can't infer dynamic user agent preferences, needs an external device database, isn't cache friendly, and depends on a passive fingerprinting surface. π
- Cookie-based approaches aren't portable across apps and servers, add extra client-side latency by requiring JavaScript execution, and aren't cache friendly. πͺ
- URL parameters are similar to cookie-based approaches. They suffer from a lack of portability and are hard to deploy, because content negotiation data has to be encoded inside the URL of each resource. π
Proactive content negotiation (Section 3.4.1 of [RFC7231]) offers a better alternative. User agents use specified, well-defined request headers to advertise their capabilities and characteristics, so servers can select (or formulate) an appropriate response based on those request headers (or on other, implicit characteristics). π
Here's the catch, though: traditional proactive content negotiation often means user agents send these request headers prolifically. π₯΄ That causes performance concerns (because it creates "bloat" in requests), and it causes privacy issues too, since passively providing that info lets servers silently fingerprint the user. π«£
This document defines Client Hints, a framework that lets servers opt in to specific proactive content negotiation features and adapt their content accordingly. It also gives guidelines for content negotiation mechanisms that use the framework. On top of that, it defines a new response header, Accept-CH, which lets an origin server explicitly ask user agents to send these headers in requests. π
Client Hints mitigate performance concerns by making sure user agents only send the request headers when they're actually going to be used. They also mitigate passive fingerprinting privacy concerns by requiring explicit opt-in, and by having the server disclose required headers through the Accept-CH response header. That turns passive fingerprinting vectors into active ones. Iconic glow-up π β¨
The document doesn't define specific usages of Client Hints. Those usages need to be defined in their own respective specifications. π
One example of such a usage is the User-Agent Client Hints [UA-CH]. π§
1.1. Notational Conventions π
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. π―
This document uses the Augmented Backus-Naur Form (ABNF) notation of [RFC5234]. π€
2. Client Hints Request Header Fields π
A Client Hints request header field is an HTTP header field that user agents use to indicate data the server can use to select an appropriate response. Each one conveys user agent preferences that the server can use to adapt and optimize the response. π
2.1. Sending Client Hints π
User agents choose which Client Hints to send in a request based on their default settings, user configuration, and server preferences expressed in Accept-CH. The user agent and server can use an opt-in mechanism (outlined below) to negotiate which header fields need to be sent for efficient content adaptation. They can also optionally use additional mechanisms, like the ones outlined in [CLIENT-HINTS-INFRASTRUCTURE], to negotiate delegation policies. Those policies control whether third parties get access to those same header fields. User agents SHOULD require an opt-in to send any hints that are not considered low-entropy. For examples of hints that expose low amounts of entropy, check the low-entropy hint table at [CLIENT-HINTS-INFRASTRUCTURE]. π
Implementers need to be aware of the fingerprinting implications when they add support for Client Hints. Follow the considerations in the Security Considerations section of this document (see Section 4). π‘οΈ
2.2. Server Processing of Client Hints π§
When a server gets a request that contains one or more Client Hints header fields, it can optimize the response based on the info in them. When it does that, and the resource is cacheable, the server MUST also generate a Vary response header field (Section 7.1.4 of [RFC7231]). That tells caches which hints can affect the selected response, and whether the selected response is appropriate for a later request. ποΈ
Servers MUST ignore hints they do not understand nor support. There's no mechanism for servers to tell user agents that hints were ignored. π€·ββοΈ
Furthermore, the server can generate additional response header fields (as specified by the hint or hints in use) that convey related values to help client processing. β¨
3. Advertising Server Support π£
Servers can advertise their support for Client Hints using the mechanism described below. πΈ
3.1. The Accept-CH Response Header Field π
The Accept-CH response header field indicates server support for the hints listed in its value. Servers that want to receive user agent information through Client Hints SHOULD add the Accept-CH response header to their responses as early as possible. β°
Accept-CH is a Structured Header [RFC8941]. Its value MUST be an sf-list (Section 3.1 of [RFC8941]) whose members are Tokens (Section 3.3.4 of [RFC8941]). Its ABNF is:
Accept-CH = sf-list
For example:
Accept-CH: Sec-CH-Example, Sec-CH-Example-2
When a user agent gets an HTTP response containing "Accept-CH", it means the origin has opted in to receive the listed request header fields for subsequent same-origin requests. The opt-in MUST be ignored if it's delivered over a non-secure transport (using a scheme different from HTTPS). It SHOULD be persisted and bound to the origin, so Client Hints can be delivered on later requests to that origin's server, for the duration of the user's session (as defined by the user agent). A new opt-in overrides previously persisted opt-in values, and it SHOULD be persisted in their place. π
Let's use the Accept-CH example above. Say it comes back in response to a user agent navigating to https://site.example, and it's delivered over a secure transport. The persisted Accept-CH preferences will then be bound to https://site.example. The user agent will use them for navigations to, for example, https://site.example/foobar.html, but not to https://foobar.site.example/. πΈοΈ It'll similarly use the preference for any same-origin resource requests initiated by the page constructed from the navigation's response (for example, to https://site.example/image.jpg), but not for cross-origin resource requests (for example, to https://thirdparty.example/resource.js). This preference also won't extend to resource requests initiated to https://site.example from other origins (for example, from navigations to https://other.example/). Main character energy, but make it scoped π¬
3.2. Interaction with Caches ποΈ
When a server selects a response based on one or more Client Hints, and the resource is cacheable, it needs to generate a Vary response header field [RFC7234]. That tells caches which hints can affect the selected response, and whether the selected response is appropriate for a later request. π§
Vary: Sec-CH-Example
The above example indicates that the cache key needs to include the Sec-CH-Example header field. π
Vary: Sec-CH-Example, Sec-CH-Example-2
The above example indicates that the cache key needs to include the Sec-CH-Example and Sec-CH-Example-2 header fields. π
4. Security Considerations π
4.1. Information Exposure
Okay bestie, this section is SERIOUS π Request header fields used by features that rely on this document expose info about the user's environment. The goal is privacy-preserving proactive content negotiation that avoids handing out passive fingerprinting vectors π΅οΈββοΈ. Still, implementers need to keep in mind that in the worst case, uncontrolled and unmonitored active fingerprinting is no better than passive fingerprinting π. To actually give users privacy benefits, user agents need to apply extra policies that stop abuse of the info exposed by features using Client Hints π‘οΈ.
The info that features expose might reveal new things about the user, so implementers ought to consider the following considerations, recommendations, and best practices π.
The core assumption here is that exposing info about the user as a request header is basically the same (security-wise) as exposing it some other way. For example, if the request's origin can read that info through JavaScript APIs and send it to its servers, that's the same deal π.
Client Hints is an explicit opt-in mechanism πββοΈ, so servers that want info about the user's environment have to actively ask for it. That lets clients and privacy researchers track which origins collect that data and maybe do something about it π. Because of the header-based opt-in, removing passive fingerprinting vectors is possible β¨. For example, the user agent can reduce the info exposed by the User-Agent string while enabling active access to that info through User-Agent Client Hints [UA-CH] π¦. Otherwise, the user agent can expose info that's already available through script (like the Save-Data Client Hints <https://wicg.github.io/savedata/#save-data-request-header-field>) without making the passive fingerprinting surface bigger πΈ. User agents that support Client Hints features which send certain info to opted-in servers SHOULD avoid sending the equivalent info passively π«Ά.
So, features relying on this document to define Client Hint headers MUST NOT provide new information that isn't otherwise made available to the application by the user agent, such as existing request headers, HTML, CSS, or JavaScript π«.
Features have to think about the following aspects of the exposed info π :
- Entropy: Exposing highly granular data can help identify users across multiple requests to different origins π. Reducing the set of header field values that can be expressed helps, or restricting them to an enumerated range where the advertised value is close to but not an exact representation of the current value. Either way, privacy goes up and linkability risk goes down, because the same value ends up being sent by multiple users π.
- Sensitivity: The feature SHOULD NOT expose user-sensitive information π. Info that's available to the application but gated behind specific user actions (like a permission prompt or user activation) SHOULD NOT be exposed as a Client Hint π.
- Change over time: The feature SHOULD NOT expose user info that changes over time, unless the state change itself is also exposed (for example, through JavaScript callbacks) β³.
Different features will sit at different points on the spectrum between low-entropy, non-sensitive, static info (like user agent info) and high-entropy, sensitive, dynamic info (like geolocation) πΊοΈ. User agents need to weigh the value a particular feature brings against these considerations, and they may want different policies for that tradeoff on a per-feature or other fine-grained basis βοΈ.
Implementers ought to consider both user-controlled and server-controlled mechanisms and policies for controlling which Client Hints header fields get advertised ποΈ:
- Implementers SHOULD restrict delivery of some or all Client Hints header fields to the opt-in origin only, unless the opt-in origin has explicitly delegated permission to another origin to request Client Hints header fields π.
- Implementers that consider user-choice mechanisms, which let users balance privacy concerns against bandwidth limitations, need to also consider that explaining the privacy implications to users (like the risks of passive fingerprinting) may be challenging or even impractical π€―.
- Implementations for specific use cases or threat models MAY avoid transmitting some or all of the Client Hints header fields π§. For example, they can avoid sending header fields that carry higher linkability risks π.
User agents MUST clear persisted opt-in preferences whenever any one of site data, browsing cache, cookies, or similar is cleared π§Ή. No exceptions, periodt π .
4.2. Deployment and Security Risks
Deploying new request headers takes several considerations π§:
- Potential conflicts due to existing use of a header field name β οΈ
- Properties of the data communicated in a header field value π¦
Authors of new Client Hints are advised to think carefully about whether they need the hints to be addable by client-side content (like scripts), or whether the Client Hints should be set exclusively by the user agent π€. In the latter case, the Sec- prefix on the header field name stops scripts and other application content from setting them in user agents π. Using the "Sec-" prefix also tells servers that the user agent, and not application content, generated the values π«‘. See [FETCH] for more information π.
By convention, request headers that are Client Hints are encouraged to use a CH- prefix, so they're easier to spot as part of this framework π. For example, CH-Foo or, with a "Sec-" prefix, Sec-CH-Foo. This makes them easier to identify programmatically, like when privacy filters strip unrecognized hints from requests π§Ό.
A Client Hints request header negotiated using the Accept-CH opt-in mechanism MUST have a field name that matches sf-token (Section 3.3.4 of [RFC8941]) π.
4.3. Abuse Detection
A user agent that tracks access to active fingerprinting info SHOULD think about emitting Client Hints headers the same way it would think about accessing the equivalent API π΅οΈ.
Researchers looking into abuse of Client Hints might check how HTTP responses to requests containing Client Hints differ from responses to requests with different values, and from responses to requests without values π¬. That could reveal which Client Hints are in use, so researchers can dig deeper into that usage π§ͺ.
5. Cost of Sending Hints πΈ
Sending Client Hints to the server increases request byte size π. Some of that increase can be softened by HTTP header compression schemes, but every new hint sent will still add some bandwidth usage π₯². Servers SHOULD take that into account when opting in to receive Client Hints, and SHOULD NOT opt in to receive hints unless they're going to be used for content adaptation purposes π§ .
Because of the bigger request size, features relying on this document to define Client Hints MAY consider restricting sending those hints to certain request destinations [FETCH], where they're more likely to be useful π―.
6. IANA Considerations ποΈ
Features relying on this document are expected to register added request header fields in the "Permanent Message Header Field Names" registry [RFC3864] π.
This document defines the "Accept-CH" HTTP response header field, and IANA has registered it in the same registry π.
6.1. Accept-CH
- Header field name:
Accept-CH - Applicable protocol: HTTP
- Status: experimental
- Author/Change controller: IETF
- Specification document(s): Section 3.1 of this RFC
- Related information: for Client Hints
7. References π
7.1. Normative References
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/info/rfc2119>.
[RFC3864] Klyne, G., Nottingham, M., and J. Mogul, "Registration
Procedures for Message Header Fields", BCP 90, RFC 3864,
DOI 10.17487/RFC3864, September 2004,
<https://www.rfc-editor.org/info/rfc3864>.
[RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax
Specifications: ABNF", STD 68, RFC 5234,
DOI 10.17487/RFC5234, January 2008,
<https://www.rfc-editor.org/info/rfc5234>.
[RFC7231] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer
Protocol (HTTP/1.1): Semantics and Content", RFC 7231,
DOI 10.17487/RFC7231, June 2014,
<https://www.rfc-editor.org/info/rfc7231>.
[RFC7234] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke,
Ed., "Hypertext Transfer Protocol (HTTP/1.1): Caching",
RFC 7234, DOI 10.17487/RFC7234, June 2014,
<https://www.rfc-editor.org/info/rfc7234>.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, <https://www.rfc-editor.org/info/rfc8174>.
[RFC8941] Nottingham, M. and P-H. Kamp, "Structured Field Values for
HTTP", RFC 8941, DOI 10.17487/RFC8941, February 2021,
<https://www.rfc-editor.org/info/rfc8941>.
7.2. Informative References
[CLIENT-HINTS-INFRASTRUCTURE]
Weiss, Y., "Client Hints Infrastructure", July 2020,
<https://wicg.github.io/client-hints-infrastructure/>.
[FETCH] WHATWG, "Fetch - Living Standard",
<https://fetch.spec.whatwg.org/>.
[RFC6265] Barth, A., "HTTP State Management Mechanism", RFC 6265,
DOI 10.17487/RFC6265, April 2011,
<https://www.rfc-editor.org/info/rfc6265>.
[UA-CH] West, M. and Y. Weiss, "User-Agent Client Hints", August
2020, <https://wicg.github.io/ua-client-hints/>.
Acknowledgements π
Huge thanks to Mark Nottingham, Julian Reschke, Chris Bentzel, Ben Greenstein, Tarun Bansal, Roy Fielding, Vasiliy Faronov, Ted Hardie, Jonas Sicking, Martin Thomson, and the many other members of the IETF HTTP Working Group for their invaluable help and feedback π«Άπ.
Authors' Addresses βοΈ
Ilya Grigorik Google
Email: ilya@igvita.com URI: https://www.igvita.com/
Yoav Weiss Google
Email: yoav@yoav.ws URI: https://blog.yoav.ws/
π¦ where this page comes from
- ietf: rfc8942 2021-02
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms