├── .github └── workflows │ └── autopublish.yml ├── .gitignore ├── .pr-preview.json ├── .travis.yml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── compile.sh ├── deploy.sh ├── deploy_key.enc ├── index.bs ├── reliability.md ├── tag-security-privacy-third-party-delegation.md └── w3c.json /.github/workflows/autopublish.yml: -------------------------------------------------------------------------------- 1 | # Create a file called .github/workflows/auto-publish.yml 2 | name: CI 3 | on: 4 | pull_request: {} 5 | push: 6 | branches: [main] 7 | jobs: 8 | main: 9 | name: Build, Validate and Deploy 10 | runs-on: ubuntu-20.04 11 | steps: 12 | - uses: actions/checkout@v2 13 | - uses: w3c/spec-prod@v2 14 | with: 15 | GH_PAGES_BRANCH: gh-pages 16 | VALIDATE_MARKUP: false -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | index.html 2 | -------------------------------------------------------------------------------- /.pr-preview.json: -------------------------------------------------------------------------------- 1 | { 2 | "src_file": "index.bs", 3 | "type": "bikeshed", 4 | "params": { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | sudo: false 3 | python: 4 | - "3.8" 5 | 6 | install: 7 | # Setup bikeshed. See https://tabatkins.github.io/bikeshed/#travis-ci 8 | - pip3 install bikeshed 9 | - bikeshed update 10 | 11 | script: 12 | - bash ./deploy.sh 13 | 14 | env: 15 | global: 16 | - ENCRYPTION_LABEL: "c80b4dc18b55" 17 | - COMMIT_AUTHOR_EMAIL: "yoav@yoav.ws" 18 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | All documentation, code and communication under this repository are covered by the [W3C Code of Ethics and Professional Conduct](https://www.w3.org/Consortium/cepc/). 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Web Platform Incubator Community Group 2 | 3 | This repository is being used for work in the W3C Web Platform Incubator Community Group, governed by the [W3C Community License 4 | Agreement (CLA)](http://www.w3.org/community/about/agreements/cla/). To make substantive contributions, 5 | you must join the CG. 6 | 7 | If you are not the sole contributor to a contribution (pull request), please identify all 8 | contributors in the pull request comment. 9 | 10 | To add a contributor (other than yourself, that's automatic), mark them one per line as follows: 11 | 12 | ``` 13 | +@github_username 14 | ``` 15 | 16 | If you added a contributor by mistake, you can remove them in a comment with: 17 | 18 | ``` 19 | -@github_username 20 | ``` 21 | 22 | If you are making a pull request on behalf of someone else but you had no part in designing the 23 | feature, you can remove yourself with the above syntax. 24 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | All Reports in this Repository are licensed by Contributors 2 | under the 3 | [W3C Software and Document License](http://www.w3.org/Consortium/Legal/2015/copyright-software-and-document). 4 | 5 | Contributions to Specifications are made under the 6 | [W3C CLA](https://www.w3.org/community/about/agreements/cla/). 7 | 8 | Contributions to Test Suites are made under the 9 | [W3C 3-clause BSD License](https://www.w3.org/Consortium/Legal/2008/03-bsd-license.html) 10 | 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Explainer 2 | 3 | Client Hints is collection of HTTP and user-agent features that enables 4 | privacy-preserving, proactive content negotiation with an explicit cross-origin 5 | delegation mechanism: 6 | 7 | * Proactive content negotiation at the HTTP layer (defined in the 8 | [IETF RFC](https://tools.ietf.org/html/rfc8942)) 9 | enables servers to request delivery of specific hints, in order to enable 10 | optimized and automated selection of resources based on a user's device, 11 | conditions and preferences, and lets clients decide which hint requests they 12 | want to grant, with per-hint and per-origin granularity. 13 | * Integration of said mechanism with web concepts (defined in this 14 | [specification](https://wicg.github.io/client-hints-infrastructure)) 15 | specification) enables browsers to benefit from content adaptation, and have it 16 | play nicely with current web restrictions (e.g. same-origin policy). 17 | * The opt-in nature of the mechanism enables browsers to advertise requested 18 | hint data (e.g. user agent and device characteristics) selectively to 19 | secure-transport origins, instead of appending such data on every outgoing 20 | request. 21 | * Origin opt-in applies to same-origin assets only and delivery to cross-origin 22 | origins is subject to explicit cross-origin delegation via Feature Policy, 23 | enabling tight control over which cross-origin origins can access requested 24 | hint data. 25 | 26 | The goal of Client Hints is to **reduce passive fingerprinting** on the web 27 | while **enabling scalable and privacy preserving content adaptation** between 28 | client and server, via a standardized set of content negotiation primitives at 29 | the HTTP and user agent levels. 30 | 31 | This document outlines the Client Hints infrastructure, explains it at a high 32 | level and points to the various specification and draft proposals in which it 33 | is officially defined. It does not describe the various features and hints 34 | which rely on this infrastructure. They will be defined in their respective 35 | specifications. 36 | 37 | # The Client Hints infrastructure 38 | 39 | How can servers opt into receiving hints from the client? How should clients 40 | send those hints? And how should that be handled across origins? 41 | 42 | ## Opt-in mechanism 43 | 44 | In order to receive Client Hints, servers must opt-in by using the HTTP 45 | response headers described in the sections below. For security and privacy 46 | reasons, the opt-in must be received on the response of the top-level 47 | navigation, over a secure connection. 48 | Servers can similarly opt-in by using the headers' HTML equivalents, the 49 | `` HTML tag and its `http-equiv` attribute. 50 | 51 | ### `Accept-CH` 52 | 53 | The `Accept-CH` header enables servers to request specific hints from the 54 | browser. The header's value is a comma separated list, where each value in that 55 | list represents a request header hint that the server is interested in 56 | receiving. 57 | 58 | If a server's response to a navigation request includes the `Accept-CH: 59 | foo, bar` header, same-origin subresource requests on the page will include the 60 | `Sec-Foo: foo-value` and `Sec-Bar: bar-value` request headers unless the 61 | client has reasons to avoid sending that information to the server. 62 | 63 | ### `Delegate-CH` 64 | 65 | The `Delegate-CH` `` HTML tag enables top level frames to request specific hints 66 | from the browser. The header's value is a semi-colon separated list (akin to the 67 | [Permissions Policy syntax](https://www.w3.org/TR/permissions-policy/#algo-parse-policy-directive)), 68 | where each value in that list represents a request header hint that the server is interested in 69 | receiving. 70 | 71 | If the HTML response to a navigation request includes the `` tag, same-origin subresource requests on the page will include 73 | the `Sec-Foo: foo-value` and `Sec-Bar: bar-value` request headers, unless the 74 | client has reasons to avoid sending that information to the server. 75 | 76 | ## Same-Origin Policy 77 | 78 | There are three important restrictions on the opt-in mechanism description above: 79 | 80 | - opt-ins will only be granted when the opt-in headers are received with a 81 | top-level navigation resource 82 | - after the opt-in, hints will only be sent with same-origin requests 83 | - any `Delegate-CH` `` HTML tags injected by javascript will be ignored 84 | 85 | Why are these limitations important? 86 | 87 | As mentioned before, we don't want the mechanism to be used to increase 88 | fingerprinting on the web. The information that Client Hints provide should 89 | generally be available through Javascript APIs (see the 90 | [Privacy Considerations](#privacy-considerations) section for more details). 91 | 92 | That means that for *active* resources (e.g. HTML), Client Hints does not 93 | increase the active fingerprinting surface. Servers serving active resources 94 | can already exfiltrate the data that hints provide, via scripts, styles or 95 | certain elements (e.g. ``). Client Hints only provides servers 96 | with a more convenient and performant way to get that information for 97 | content-negotiation purposes and ensures that authors and user agents have 98 | ultimate control over which servers get what information. 99 | 100 | Client Hints also allow this information to be collected on *passive* 101 | sub-resources (e.g. images). We don't want cross-origin origins to be able to 102 | exfiltrate data about the client/user without explicit permission from the 103 | top-level origin. And we certainly don't want them to be able to exfiltrate it 104 | cross-origin, beyond the lifetime of the current navigation. 105 | 106 | Therefore, by default, Client Hints opt-in is only valid when delivered on 107 | top-level navigation requests before any scripts execute, and, by default, 108 | applies only to same-origin resources. Cross-origin requests must only receive 109 | hints when explicit permission is given by the top-level document's origin. 110 | 111 | ## Cross-origin hint delegation 112 | 113 | Why do we need cross-origin Client Hints? 114 | 115 | As the purpose of for client hints is to enable content negotiation at scale, and 116 | as many optimization services are offered over different origins than the main 117 | page's origin (e.g., CDNs, resource-specific hosting services, or dedicated, 118 | resource-specific, first-party sub-domains), cross-origin support is a vital 119 | part of Client Hints. 120 | 121 | In order to support these use-cases, we have defined delegation of Client Hints 122 | cross-origin, using a HTTP Permissions Policy or HTML Feature Policy. 123 | 124 | ### HTTP Example 125 | 126 | A server sending the following header `Permissions-Policy: ch-example=( 127 | "foo.com" "bar.com"), ch-example-2="foobar.org"` as part of a top-level navigation 128 | response will delegate the `example` hint to the "foo.com" and "bar.com" 129 | origins and `example-2` to the "foobar.org" origin. So, the client would know 130 | that it had explicit permission from the top-level origin to send these hints 131 | cross-origin, so that these cross-origin origins could perform content 132 | adaptation based on them. 133 | 134 | ### HTML Example 135 | 136 | A top level frame containing the following `` HTML tag: `` will delegate the 138 | `example` hint to the "foo.com" and "bar.com" origins and `example-2` to the "foobar.org" 139 | origin. So, the client would know that it had explicit permission from the top-level origin to 140 | send these hints cross-origin, so that these cross-origin origins could perform content 141 | adaptation based on them. 142 | 143 | ### Privacy implications 144 | 145 | Why is it privacy-safe for pages to delegate hints to certain cross-origin origins? 146 | 147 | Since we're treating Client Hints as an active fingerprinting equivalent, we 148 | are comfortable with the information it exposes to the top-level origin, as the same 149 | information is already freely available in the equivalent Javascript APIs. 150 | Similarly, cross-origin delegation is safe because top-level origin are already able to use 151 | other means (such as link decoration), to achieve the same information sharing 152 | cross-origin, in less convenient and performant ways. 153 | 154 | Further, the HTML delegation can only occur when the `` HTML tag is not injected 155 | via javascript, ensuring scripts cannot delegate hints in ways that relax the restrictions 156 | the top-level content author did not permit. 157 | 158 | In short, top-level origins already have the power to share information about the 159 | client cross-origin. Cross-origin delegation of Client Hints provides a 160 | cleaner pathway for that sharing, and ensures that top-level origin, and 161 | ultimately clients, are aware and in control of what is being shared with who. 162 | 163 | ## `Sec-` prefix 164 | 165 | Adding new request headers increases the risk that legacy server systems 166 | already use those values for a different purpose. Changing the request header 167 | values that such legacy systems receive may result in server bugs. 168 | 169 | While that risk is significantly mitigated by the opt-in mechanisms of Client 170 | Hints (as servers would be opting in to get Client Hints headers), we feel 171 | it is required to mitigate it even further. So, Client Hints request headers 172 | should be preceded by the `Sec-` prefix. 173 | 174 | The `Sec-` prefix also ensures that these headers are only generated by the 175 | browser and not added by potentially-malicious developers. That gives servers 176 | further guarantees when processing those headers. It may also enable us to 177 | simplify the related Fetch processing model, as it clearly indicates that these 178 | are headers that were added by the user agent. 179 | 180 | ## Caching considerations 181 | 182 | When adapting content to specific Client Hints request headers, servers should 183 | add the `Vary` header to their responses, with a value of each Client Hint 184 | header used, in order to indicate such adaptation to caches, and make sure that 185 | Client-Hint-negotiated resources are not cached using only their URL as the 186 | cache key. 187 | 188 | This is also the reason that each Client Hint is represented using a separate 189 | header. Ensuring that each hint has its own header reduces cache variance in 190 | responses that may rely on some hints, but not others. 191 | 192 | # Security and privacy considerations 193 | 194 | There are a few key mechanisms we already discussed that are part of the Client 195 | Hints infrastructure, which enable secure and privacy-preserving deployment 196 | of Client Hints: 197 | 198 | * Server opt-ins must be delivered on a top-level navigation request, over a 199 | secure connection. 200 | * Hints are only delivered with same-origin requests, over a secure connection. 201 | * If the top-level origin wants hints to be delivered to certain cross-origin origins, 202 | the top-level origin can explicitly delegate specific hints to specific origins. 203 | * Hints are `Sec-` prefixed, to provide servers with more confidence regarding 204 | the values they deliver, as well as to avoid legacy server bugs. 205 | 206 | Beyond that, when implementing Client Hints, browsers should make sure that 207 | certain privacy-related precautions are being taken: 208 | 209 | * Client Hint features should not be shipped unless there is a Javascript-based 210 | equivalent API, which enables developers access to the same data and is 211 | deemed privacy-safe to ship 212 | - This follows Extensible Web principles — we want the 213 | shipped features to be polyfillable (Even if `Sec-` headers cannot 214 | be added by developers) 215 | - As discussed above, from a privacy perspective, we consider Client Hints to 216 | be a potential active fingerprinting vector equivalent. Therefore, it is 217 | only safe to ship it with hints that provide information which is already 218 | available through other active fingerprinting means, such as a Javascript 219 | API. 220 | * Browsers should turn off hints when users choose to turn off Javascript 221 | - If the user has turned off Javascript, Javascript-based active 222 | fingerprinting vectors have been disabled. Since that could have been the 223 | user's intention when turning off scripting, browsers should similarly turn 224 | off Client Hints. 225 | * Browsers can choose to omit or to lie about certain Client Hints to increase 226 | their users' privacy 227 | - Browsers are free to take privacy-enhancing heuristics into account when 228 | deciding to respect the server's opt-in to receive them. Similar heuristics 229 | can also be used when deciding what values to send. 230 | 231 | # Motivation and trade-offs 232 | 233 | ## Proactive content negotiation and its benefits 234 | 235 | When choosing a solution that will provide alternative resources to the user's 236 | browser based on various factors, we are faced with a design dillema: Either 237 | the developer can provide the browser with a list of all potential URLs and let 238 | the browser choose the best one, or can use **content negotiation** and let the 239 | server pick the best-fit resource variant. 240 | 241 | The former option certainly has its place, and it is used successfully across 242 | the web in examples like ``, `srcset`, `