Internet-Draft | No-Vary-Search | June 2024 |
Denicola & Roman | Expires 6 December 2024 | [Page] |
- Workgroup:
- HyperText Transfer Protocol
- Internet-Draft:
- draft-wicg-http-no-vary-search-01
- Published:
- Intended Status:
- Informational
- Expires:
No-Vary-Search
Abstract
A proposed HTTP header field for changing how URL search parameters impact caching.¶
About This Document
This note is to be removed before publishing as an RFC.¶
The latest revision of this draft can be found at https://jeremyroman.github.io/http-no-vary-search/draft-wicg-http-no-vary-search.html. Status information for this document may be found at https://datatracker.ietf.org/doc/draft-wicg-http-no-vary-search/.¶
Source for this draft and an issue tracker can be found at https://github.com/jeremyroman/http-no-vary-search.¶
Status of This Memo
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 6 December 2024.¶
Copyright Notice
Copyright (c) 2024 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, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
1. Conventions and Definitions
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 also adopts some conventions and notation typical in WHATWG and W3C usage, especially as it relates to algorithms. See [WHATWG-INFRA].¶
2. HTTP header field definition
The No-Vary-Search
HTTP header field is a structured field [STRUCTURED-FIELDS] whose value must be a dictionary (Section 3.2 of [STRUCTURED-FIELDS]).¶
It has the following authoring conformance requirements:¶
-
The dictionary must only contain entries whose keys are one of
key-order
,params
,except
.¶ -
If present, the
key-order
entry's value must be a boolean (Section 3.3.6 of [STRUCTURED-FIELDS]).¶ -
If present, the
params
entry's value must be either a boolean (Section 3.3.6 of [STRUCTURED-FIELDS]) or an inner list (Section 3.1.1 of [STRUCTURED-FIELDS]).¶ -
If present, the
except
entry's value must be an inner list (Section 3.1.1 of [STRUCTURED-FIELDS]).¶ -
The
except
entry must only be present if theparams
entry is also present, and theparams
entry's value is the boolean value true.¶
3. Data model
A URL search variance consists of the following:¶
- no-vary params
-
either the special value wildcard or a list of strings¶
- vary params
-
either the special value wildcard or a list of strings¶
- vary on key order
-
a boolean¶
The default URL search variance is a URL search variance whose no-vary params is an empty list, vary params is wildcard, and vary on key order is true.¶
The obtain a URL search variance algorithm (Section 4.2) ensures that all URL search variances obey the following constraints:¶
4. Parsing
4.1. Parse a URL search variance
To parse a URL search variance given value:¶
-
If value is null, then return the default URL search variance.¶
-
If value's keys contains anything other than "
key-order
", "params
", or "except
", then return the default URL search variance.¶ -
Let result be a new URL search variance.¶
-
Set result's vary on key order to true.¶
-
If value["
key-order
"] exists:¶ -
If value["
params
"] exists:¶-
If value["
params
"] is a boolean:¶ -
Otherwise, if value["
params
"] is an array:¶-
If any item in value["
params
"] is not a string, then return the default URL search variance.¶ -
Set result's no-vary params to the result of applying parse a key (Section 4.3) to each item in value["
params
"].¶ -
Set result's vary params to wildcard.¶
-
-
Otherwise, return the default URL search variance.¶
-
-
If value["
except
"] exists:¶-
If value["
params
"] is not true, then return the default URL search variance.¶ -
If value["
except
"] is not an array, then return the default URL search variance.¶ -
If any item in value["
except
"] is not a string, then return the default URL search variance.¶ -
Set result's vary params to the result of applying parse a key (Section 4.3) to each item in value["
except
"].¶
-
-
Return result.¶
4.2. Obtain a URL search variance
To obtain a URL search variance given a response response:¶
-
Let fieldValue be the result of getting a structured field value [FETCH] given `
No-Vary-Search
` and "dictionary
" from response's header list.¶ -
Return the result of parsing a URL search variance (Section 4.1) given fieldValue. ¶
4.2.1. Examples
The following illustrates how various inputs are parsed, in terms of their impacting on the resulting no-vary params and vary params:¶
Input | Result |
---|---|
No-Vary-Search: params
|
no-vary params: wildcard vary params: (empty list) |
No-Vary-Search: params=("a")
|
no-vary params: « "a " »vary params: wildcard |
No-Vary-Search: params, except=("x")
|
no-vary params: wildcard vary params: « " x " » |
The following inputs are all invalid and will cause the default URL search variance to be returned:¶
-
No-Vary-Search: unknown-key
¶ -
No-Vary-Search: key-order="not a boolean"
¶ -
No-Vary-Search: params="not a boolean or inner list"
¶ -
No-Vary-Search: params=(not-a-string)
¶ -
No-Vary-Search: params=("a"), except=("x")
¶ -
No-Vary-Search: params=(), except=()
¶ -
No-Vary-Search: params=?0, except=("x")
¶ -
No-Vary-Search: params, except=(not-a-string)
¶ -
No-Vary-Search: params, except="not an inner list"
¶ -
No-Vary-Search: params, except=?1
¶ -
No-Vary-Search: except=("x")
¶ -
No-Vary-Search: except=()
¶
The following inputs are valid, but somewhat unconventional. They are shown alongside their more conventional form.¶
Input | Conventional form |
---|---|
No-Vary-Search: params=?1
|
No-Vary-Search: params
|
No-Vary-Search: key-order=?1
|
No-Vary-Search: key-order
|
No-Vary-Search: params, key-order, except=("x")
|
No-Vary-Search: key-order, params, except=("x")
|
No-Vary-Search: params=?0
|
(omit the header) |
No-Vary-Search: params=()
|
(omit the header) |
No-Vary-Search: key-order=?0
|
(omit the header) |
4.3. Parse a key
To parse a key given an ASCII string keyString:¶
-
Let keyBytes be the isomorphic encoding [WHATWG-INFRA] of keyString.¶
-
Replace any 0x2B (+) in keyBytes with 0x20 (SP).¶
-
Let keyBytesDecoded be the percent-decoding [WHATWG-URL] of keyBytes.¶
-
Let keyStringDecoded be the UTF-8 decoding without BOM [WHATWG-ENCODING] of keyBytesDecoded.¶
-
Return keyStringDecoded.¶
4.3.1. Examples
The parse a key algorithm allows encoding non-ASCII key strings in the ASCII structured header format, similar to how the application/x-www-form-urlencoded format [WHATWG-URL] allows encoding an entire entry list of keys and values in ASCII URL format. For example,¶
will result in a URL search variance whose vary params are « "é 気
" ». As explained in a later example, the canonicalization process during equivalence testing means this will treat as equivalent URL strings such as:¶
-
https://example.com/?é 気=1
¶ -
https://example.com/?é+気=2
¶ -
https://example.com/?%C3%A9%20気=3
¶ -
https://example.com/?%C3%A9+%E6%B0%97=4
¶
and so on, since they all are parsed [WHATWG-URL] to having the same key "é 気
".¶
5. Comparing
Two URLs [WHATWG-URL] urlA and urlB are equivalent modulo search variance given a URL search variance searchVariance if the following algorithm returns true:¶
-
If the scheme, username, password, host, port, or path of urlA and urlB differ, then return false.¶
-
If searchVariance is equivalent to the default URL search variance, then:¶
In this case, even URL pairs that might appear the same after running the application/x-www-form-urlencoded parser [WHATWG-URL] on their queries, such as
https://example.com/a
andhttps://example.com/a?
, orhttps://example.com/foo?a=b&&&c
andhttps://example.com/foo?a=b&c=
, will be treated as inequivalent.¶ -
Let searchParamsA and searchParamsB be empty lists.¶
-
If wrlA's query is not null, then set searchParamsA to the result of running the application/x-www-form-urlencoded parser [WHATWG-URL] given the isomorphic encoding [WHATWG-INFRA] of urlA's query.¶
-
If wrlB's query is not null, then set searchParamsB to the result of running the application/x-www-form-urlencoded parser [WHATWG-URL] given the isomorphic encoding [WHATWG-INFRA] of urlB's query.¶
-
If searchVariance's no-vary params is a list, then:¶
-
Otherwise, if searchVariance's vary params is a list, then:¶
-
If searchVariance's vary on key order is false, then:¶
-
Let keyLessThan be an algorithm taking as inputs two pairs (keyA, valueA) and (keyB, valueB), which returns whether keyA is code unit less than [WHATWG-INFRA] keyB.¶
-
Set searchParamsA to the result of sorting searchParamsA in ascending order with keyLessThan.¶
-
Set searchParamsB to the result of sorting searchParamsB in ascending order with keyLessThan.¶
-
-
If searchParamsA's size is not equal to searchParamsB's size, then return false.¶
-
Let i be 0.¶
-
While i < searchParamsA's size:¶
-
Return true.¶
5.1. Examples
Due to how the application/x-www-form-urlencoded parser canonicalizes query strings, there are some cases where query strings which do not appear obviously equivalent, will end up being treated as equivalent after parsing.¶
So, for example, given any non-default value for No-Vary-Search
, such as No-Vary-Search: key-order
, we will have the following equivalences:¶
-
https://example.com
https://example.com/?
- A null query is parsed the same as an empty string¶
-
https://example.com/?a=x
https://example.com/?%61=%78
- Parsing performs percent-decoding¶
-
https://example.com/?a=é
https://example.com/?a=%C3%A9
- Parsing performs percent-decoding¶
-
https://example.com/?a=%f6
https://example.com/?a=%ef%bf%bd
- Both values are parsed as U+FFFD (�)¶
-
https://example.com/?a=x&&&&
https://example.com/?a=x
- Parsing splits on
&
and discards empty strings¶ -
https://example.com/?a=
https://example.com/?a
- Both parse as having an empty string value for
a
¶ -
https://example.com/?a=%20
https://example.com/?a=+
https://example.com/?a= &
-
+
and%20
are both parsed as U+0020 SPACE¶
6. Security Considerations
The main risk to be aware of is the impact of mismatched URLs. In particular, this could cause the user to see a response that was originally fetched from a URL different from the one displayed when they hovered a link, or the URL displayed in the URL bar.¶
However, since the impact is limited to query parameters, this does not cross the relevant security boundary, which is the origin [HTML]. (Or perhaps just the host, from the perspective of web browser security UI. [WHATWG-URL]) Indeed, we have already given origins complete control over how they present the (URL, reponse body) pair, including on the client side via technology such as history.replaceState() or service workers.¶
7. Privacy Considerations
This proposal is adjacent to the highly-privacy-relevant space of navigational tracking, which often uses query parameters to pass along user identifiers. However, we believe this proposal itself does not have privacy impacts. It does not interfere with existing navigational tracking mitigations, or any known future ones being contemplated. Indeed, if a page were to encode user identifiers in its URL, the only ability this proposal gives is to reduce such user tracking by preventing server processing of such user IDs (since the server is bypassed in favor of the cache). [NAV-TRACKING-MITIGATIONS]¶
8. IANA Considerations
TODO IANA¶
9. References
9.1. Normative References
- [FETCH]
- van Kesteren, A., "Fetch Living Standard", n.d., <https://fetch.spec.whatwg.org/>. WHATWG
- [RFC2119]
- Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/rfc/rfc2119>.
- [RFC8174]
- Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/rfc/rfc8174>.
- [STRUCTURED-FIELDS]
- Nottingham, M. and P. Kamp, "Structured Field Values for HTTP", RFC 8941, DOI 10.17487/RFC8941, , <https://www.rfc-editor.org/rfc/rfc8941>.
- [WHATWG-ENCODING]
- van Kesteren, A., "Encoding Living Standard", n.d., <https://encoding.spec.whatwg.org/>. WHATWG
- [WHATWG-INFRA]
- van Kesteren, A. and D. Denicola, "Infra Living Standard", n.d., <https://infra.spec.whatwg.org/>. WHATWG
- [WHATWG-URL]
- van Kesteren, A., "URL Living Standard", n.d., <https://url.spec.whatwg.org/>. WHATWG
9.2. Informative References
- [HTML]
- van Kesteren, A., "HTML Living Standard", n.d., <https://html.spec.whatwg.org/>. WHATWG
- [NAV-TRACKING-MITIGATIONS]
- Snyder, P. and J. Yasskin, "Navigational-Tracking Mitigations", n.d., <https://privacycg.github.io/nav-tracking-mitigations/>. W3C Privacy CG
Acknowledgments
TODO acknowledge.¶
Index
-
-
- default URL search variance
-
Section 3, Paragraph 3; Section 4.1, Paragraph 2.1.1; Section 4.1, Paragraph 2.2.1; Section 4.1, Paragraph 2.5.2.1.1; Section 4.1, Paragraph 2.6.2.2.2.1.1; Section 4.1, Paragraph 2.6.2.3.1; Section 4.1, Paragraph 2.7.2.1.1; Section 4.1, Paragraph 2.7.2.2.1; Section 4.1, Paragraph 2.7.2.3.1; Section 4.1, Paragraph 3.1; Section 4.2.1, Paragraph 3; Section 5, Paragraph 2.2.1¶
-
-
-
- equivalent modulo search variance
-
-
-
- obtain a URL search variance
-
Section 2, Paragraph 4.1; Section 3, Paragraph 4; Section 4.2, Paragraph 1¶
-
-
-
- parse a key
-
Section 4.1, Paragraph 2.6.2.2.2.2.1; Section 4.1, Paragraph 2.7.2.4.1; Section 4.3, Paragraph 1; Section 4.3.1, Paragraph 1¶
- parse a URL search variance
-