draft-ietf-httpbis-rfc6265bis-07.txt | draft-ietf-httpbis-rfc6265bis-latest.txt | |||
---|---|---|---|---|
HTTP Working Group M. West, Ed. | HTTP Working Group L. Chen, Ed. | |||
Internet-Draft Google, Inc | Internet-Draft Google LLC | |||
Obsoletes: 6265 (if approved) J. Wilander, Ed. | Obsoletes: 6265 (if approved) S. Englehardt, Ed. | |||
Intended status: Standards Track Apple, Inc | Intended status: Standards Track Mozilla | |||
Expires: June 10, 2021 December 7, 2020 | Expires: October 15, 2021 M. West, Ed. | |||
Google LLC | ||||
J. Wilander, Ed. | ||||
Apple, Inc | ||||
April 13, 2021 | ||||
Cookies: HTTP State Management Mechanism | Cookies: HTTP State Management Mechanism | |||
draft-ietf-httpbis-rfc6265bis-07 | draft-ietf-httpbis-rfc6265bis-latest | |||
Abstract | Abstract | |||
This document defines the HTTP Cookie and Set-Cookie header fields. | This document defines the HTTP Cookie and Set-Cookie header fields. | |||
These header fields can be used by HTTP servers to store state | These header fields can be used by HTTP servers to store state | |||
(called cookies) at HTTP user agents, letting the servers maintain a | (called cookies) at HTTP user agents, letting the servers maintain a | |||
stateful session over the mostly stateless HTTP protocol. Although | stateful session over the mostly stateless HTTP protocol. Although | |||
cookies have many historical infelicities that degrade their security | cookies have many historical infelicities that degrade their security | |||
and privacy, the Cookie and Set-Cookie header fields are widely used | and privacy, the Cookie and Set-Cookie header fields are widely used | |||
on the Internet. This document obsoletes RFC 6265. | on the Internet. This document obsoletes RFC 6265. | |||
skipping to change at page 1, line 46 ¶ | skipping to change at page 2, line 4 ¶ | |||
Internet-Drafts are working documents of the Internet Engineering | Internet-Drafts are working documents of the Internet Engineering | |||
Task Force (IETF). Note that other groups may also distribute | Task Force (IETF). Note that other groups may also distribute | |||
working documents as Internet-Drafts. The list of current Internet- | working documents as Internet-Drafts. The list of current Internet- | |||
Drafts is at https://datatracker.ietf.org/drafts/current/. | Drafts is at https://datatracker.ietf.org/drafts/current/. | |||
Internet-Drafts are draft documents valid for a maximum of six months | Internet-Drafts are draft documents valid for a maximum of six months | |||
and may be updated, replaced, or obsoleted by other documents at any | and may be updated, replaced, or obsoleted by other documents at any | |||
time. It is inappropriate to use Internet-Drafts as reference | time. It is inappropriate to use Internet-Drafts as reference | |||
material or to cite them other than as "work in progress." | material or to cite them other than as "work in progress." | |||
This Internet-Draft will expire on October 15, 2021. | ||||
This Internet-Draft will expire on June 10, 2021. | ||||
Copyright Notice | Copyright Notice | |||
Copyright (c) 2020 IETF Trust and the persons identified as the | Copyright (c) 2021 IETF Trust and the persons identified as the | |||
document authors. All rights reserved. | document authors. All rights reserved. | |||
This document is subject to BCP 78 and the IETF Trust's Legal | This document is subject to BCP 78 and the IETF Trust's Legal | |||
Provisions Relating to IETF Documents | Provisions Relating to IETF Documents | |||
(https://trustee.ietf.org/license-info) in effect on the date of | (https://trustee.ietf.org/license-info) in effect on the date of | |||
publication of this document. Please review these documents | publication of this document. Please review these documents | |||
carefully, as they describe your rights and restrictions with respect | carefully, as they describe your rights and restrictions with respect | |||
to this document. Code Components extracted from this document must | to this document. Code Components extracted from this document must | |||
include Simplified BSD License text as described in Section 4.e of | include Simplified BSD License text as described in Section 4.e of | |||
the Trust Legal Provisions and are provided without warranty as | the Trust Legal Provisions and are provided without warranty as | |||
skipping to change at page 3, line 22 ¶ | skipping to change at page 3, line 24 ¶ | |||
5.3.3. The Domain Attribute . . . . . . . . . . . . . . . . 26 | 5.3.3. The Domain Attribute . . . . . . . . . . . . . . . . 26 | |||
5.3.4. The Path Attribute . . . . . . . . . . . . . . . . . 27 | 5.3.4. The Path Attribute . . . . . . . . . . . . . . . . . 27 | |||
5.3.5. The Secure Attribute . . . . . . . . . . . . . . . . 27 | 5.3.5. The Secure Attribute . . . . . . . . . . . . . . . . 27 | |||
5.3.6. The HttpOnly Attribute . . . . . . . . . . . . . . . 27 | 5.3.6. The HttpOnly Attribute . . . . . . . . . . . . . . . 27 | |||
5.3.7. The SameSite Attribute . . . . . . . . . . . . . . . 27 | 5.3.7. The SameSite Attribute . . . . . . . . . . . . . . . 27 | |||
5.4. Storage Model . . . . . . . . . . . . . . . . . . . . . . 28 | 5.4. Storage Model . . . . . . . . . . . . . . . . . . . . . . 28 | |||
5.5. The Cookie Header . . . . . . . . . . . . . . . . . . . . 34 | 5.5. The Cookie Header . . . . . . . . . . . . . . . . . . . . 34 | |||
6. Implementation Considerations . . . . . . . . . . . . . . . . 36 | 6. Implementation Considerations . . . . . . . . . . . . . . . . 36 | |||
6.1. Limits . . . . . . . . . . . . . . . . . . . . . . . . . 36 | 6.1. Limits . . . . . . . . . . . . . . . . . . . . . . . . . 36 | |||
6.2. Application Programming Interfaces . . . . . . . . . . . 36 | 6.2. Application Programming Interfaces . . . . . . . . . . . 36 | |||
6.3. IDNA Dependency and Migration . . . . . . . . . . . . . . 36 | 6.3. IDNA Dependency and Migration . . . . . . . . . . . . . . 37 | |||
7. Privacy Considerations . . . . . . . . . . . . . . . . . . . 37 | 7. Privacy Considerations . . . . . . . . . . . . . . . . . . . 37 | |||
7.1. Third-Party Cookies . . . . . . . . . . . . . . . . . . . 37 | 7.1. Third-Party Cookies . . . . . . . . . . . . . . . . . . . 37 | |||
7.2. User Controls . . . . . . . . . . . . . . . . . . . . . . 38 | 7.2. User Controls . . . . . . . . . . . . . . . . . . . . . . 38 | |||
7.3. Expiration Dates . . . . . . . . . . . . . . . . . . . . 38 | 7.3. Expiration Dates . . . . . . . . . . . . . . . . . . . . 38 | |||
8. Security Considerations . . . . . . . . . . . . . . . . . . . 38 | 8. Security Considerations . . . . . . . . . . . . . . . . . . . 38 | |||
8.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . 38 | 8.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . 38 | |||
8.2. Ambient Authority . . . . . . . . . . . . . . . . . . . . 39 | 8.2. Ambient Authority . . . . . . . . . . . . . . . . . . . . 39 | |||
8.3. Clear Text . . . . . . . . . . . . . . . . . . . . . . . 39 | 8.3. Clear Text . . . . . . . . . . . . . . . . . . . . . . . 39 | |||
8.4. Session Identifiers . . . . . . . . . . . . . . . . . . . 40 | 8.4. Session Identifiers . . . . . . . . . . . . . . . . . . . 40 | |||
8.5. Weak Confidentiality . . . . . . . . . . . . . . . . . . 41 | 8.5. Weak Confidentiality . . . . . . . . . . . . . . . . . . 41 | |||
8.6. Weak Integrity . . . . . . . . . . . . . . . . . . . . . 41 | 8.6. Weak Integrity . . . . . . . . . . . . . . . . . . . . . 41 | |||
8.7. Reliance on DNS . . . . . . . . . . . . . . . . . . . . . 42 | 8.7. Reliance on DNS . . . . . . . . . . . . . . . . . . . . . 42 | |||
8.8. SameSite Cookies . . . . . . . . . . . . . . . . . . . . 42 | 8.8. SameSite Cookies . . . . . . . . . . . . . . . . . . . . 43 | |||
8.8.1. Defense in depth . . . . . . . . . . . . . . . . . . 42 | 8.8.1. Defense in depth . . . . . . . . . . . . . . . . . . 43 | |||
8.8.2. Top-level Navigations . . . . . . . . . . . . . . . . 43 | 8.8.2. Top-level Navigations . . . . . . . . . . . . . . . . 43 | |||
8.8.3. Mashups and Widgets . . . . . . . . . . . . . . . . . 43 | 8.8.3. Mashups and Widgets . . . . . . . . . . . . . . . . . 44 | |||
8.8.4. Server-controlled . . . . . . . . . . . . . . . . . . 44 | 8.8.4. Server-controlled . . . . . . . . . . . . . . . . . . 44 | |||
9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 44 | 8.8.5. Reload navigations . . . . . . . . . . . . . . . . . 44 | |||
9.1. Cookie . . . . . . . . . . . . . . . . . . . . . . . . . 44 | 9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 45 | |||
9.2. Set-Cookie . . . . . . . . . . . . . . . . . . . . . . . 44 | 9.1. Cookie . . . . . . . . . . . . . . . . . . . . . . . . . 45 | |||
9.3. Cookie Attribute Registry . . . . . . . . . . . . . . . . 45 | 9.2. Set-Cookie . . . . . . . . . . . . . . . . . . . . . . . 45 | |||
9.3.1. Procedure . . . . . . . . . . . . . . . . . . . . . . 45 | 9.3. Cookie Attribute Registry . . . . . . . . . . . . . . . . 46 | |||
9.3.2. Registration . . . . . . . . . . . . . . . . . . . . 45 | 9.3.1. Procedure . . . . . . . . . . . . . . . . . . . . . . 46 | |||
10. References . . . . . . . . . . . . . . . . . . . . . . . . . 45 | 9.3.2. Registration . . . . . . . . . . . . . . . . . . . . 46 | |||
10.1. Normative References . . . . . . . . . . . . . . . . . . 45 | 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 46 | |||
10.2. Informative References . . . . . . . . . . . . . . . . . 47 | 10.1. Normative References . . . . . . . . . . . . . . . . . . 46 | |||
10.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 49 | 10.2. Informative References . . . . . . . . . . . . . . . . . 48 | |||
Appendix A. Changes . . . . . . . . . . . . . . . . . . . . . . 50 | 10.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 50 | |||
A.1. draft-ietf-httpbis-rfc6265bis-00 . . . . . . . . . . . . 50 | Appendix A. Changes . . . . . . . . . . . . . . . . . . . . . . 52 | |||
A.2. draft-ietf-httpbis-rfc6265bis-01 . . . . . . . . . . . . 50 | A.1. draft-ietf-httpbis-rfc6265bis-00 . . . . . . . . . . . . 52 | |||
A.3. draft-ietf-httpbis-rfc6265bis-02 . . . . . . . . . . . . 51 | A.2. draft-ietf-httpbis-rfc6265bis-01 . . . . . . . . . . . . 52 | |||
A.4. draft-ietf-httpbis-rfc6265bis-03 . . . . . . . . . . . . 52 | A.3. draft-ietf-httpbis-rfc6265bis-02 . . . . . . . . . . . . 52 | |||
A.5. draft-ietf-httpbis-rfc6265bis-04 . . . . . . . . . . . . 52 | A.4. draft-ietf-httpbis-rfc6265bis-03 . . . . . . . . . . . . 53 | |||
A.6. draft-ietf-httpbis-rfc6265bis-05 . . . . . . . . . . . . 52 | A.5. draft-ietf-httpbis-rfc6265bis-04 . . . . . . . . . . . . 53 | |||
A.7. draft-ietf-httpbis-rfc6265bis-06 . . . . . . . . . . . . 52 | A.6. draft-ietf-httpbis-rfc6265bis-05 . . . . . . . . . . . . 53 | |||
A.8. draft-ietf-httpbis-rfc6265bis-07 . . . . . . . . . . . . 53 | A.7. draft-ietf-httpbis-rfc6265bis-06 . . . . . . . . . . . . 54 | |||
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 53 | A.8. draft-ietf-httpbis-rfc6265bis-07 . . . . . . . . . . . . 54 | |||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 53 | A.9. draft-ietf-httpbis-rfc6265bis-08 . . . . . . . . . . . . 54 | |||
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 55 | ||||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 55 | ||||
1. Introduction | 1. Introduction | |||
This document defines the HTTP Cookie and Set-Cookie header fields. | This document defines the HTTP Cookie and Set-Cookie header fields. | |||
Using the Set-Cookie header field, an HTTP server can pass name/value | Using the Set-Cookie header field, an HTTP server can pass name/value | |||
pairs and associated metadata (called cookies) to a user agent. When | pairs and associated metadata (called cookies) to a user agent. When | |||
the user agent makes subsequent requests to the server, the user | the user agent makes subsequent requests to the server, the user | |||
agent uses the metadata and other information to determine whether to | agent uses the metadata and other information to determine whether to | |||
return the name/value pairs in the Cookie header. | return the name/value pairs in the Cookie header. | |||
skipping to change at page 6, line 26 ¶ | skipping to change at page 6, line 29 ¶ | |||
The term request-uri refers to "request-target" as defined in | The term request-uri refers to "request-target" as defined in | |||
Section 5.3 of [RFC7230]. | Section 5.3 of [RFC7230]. | |||
Two sequences of octets are said to case-insensitively match each | Two sequences of octets are said to case-insensitively match each | |||
other if and only if they are equivalent under the i;ascii-casemap | other if and only if they are equivalent under the i;ascii-casemap | |||
collation defined in [RFC4790]. | collation defined in [RFC4790]. | |||
The term string means a sequence of non-NUL octets. | The term string means a sequence of non-NUL octets. | |||
The terms "active document", "ancestor browsing context", "browsing | The terms "active document", "ancestor browsing context", "browsing | |||
context", "dedicated worker", "Document", "WorkerGlobalScope", | context", "dedicated worker", "Document", "nested browsing context", | |||
"sandboxed origin browsing context flag", "parent browsing context", | "opaque origin", "parent browsing context", "sandboxed origin | |||
"shared worker", "the worker's Documents", "nested browsing context", | browsing context flag", "shared worker", "the worker's Documents", | |||
and "top-level browsing context" are defined in [HTML]. | "top-level browsing context", and "WorkerGlobalScope" are defined in | |||
[HTML]. | ||||
"Service Workers" are defined in the Service Workers specification | "Service Workers" are defined in the Service Workers specification | |||
[SERVICE-WORKERS]. | [SERVICE-WORKERS]. | |||
The term "origin", the mechanism of deriving an origin from a URI, | The term "origin", the mechanism of deriving an origin from a URI, | |||
and the "the same" matching algorithm for origins are defined in | and the "the same" matching algorithm for origins are defined in | |||
[RFC6454]. | [RFC6454]. | |||
"Safe" HTTP methods include "GET", "HEAD", "OPTIONS", and "TRACE", as | "Safe" HTTP methods include "GET", "HEAD", "OPTIONS", and "TRACE", as | |||
defined in Section 4.2.1 of [RFC7231]. | defined in Section 4.2.1 of [RFC7231]. | |||
skipping to change at page 6, line 51 ¶ | skipping to change at page 7, line 6 ¶ | |||
A domain's "public suffix" is the portion of a domain that is | A domain's "public suffix" is the portion of a domain that is | |||
controlled by a public registry, such as "com", "co.uk", and | controlled by a public registry, such as "com", "co.uk", and | |||
"pvt.k12.wy.us". A domain's "registrable domain" is the domain's | "pvt.k12.wy.us". A domain's "registrable domain" is the domain's | |||
public suffix plus the label to its left. That is, for | public suffix plus the label to its left. That is, for | |||
"https://www.site.example", the public suffix is "example", and the | "https://www.site.example", the public suffix is "example", and the | |||
registrable domain is "site.example". Whenever possible, user agents | registrable domain is "site.example". Whenever possible, user agents | |||
SHOULD use an up-to-date public suffix list, such as the one | SHOULD use an up-to-date public suffix list, such as the one | |||
maintained by the Mozilla project at [PSL]. | maintained by the Mozilla project at [PSL]. | |||
The term "request", as well as a request's "client", "current url", | The term "request", as well as a request's "client", "current url", | |||
"method", and "target browsing context", are defined in [FETCH]. | "method", "target browsing context", and "url list", are defined in | |||
[FETCH]. | ||||
3. Overview | 3. Overview | |||
This section outlines a way for an origin server to send state | This section outlines a way for an origin server to send state | |||
information to a user agent and for the user agent to return the | information to a user agent and for the user agent to return the | |||
state information to the origin server. | state information to the origin server. | |||
To store state, the origin server includes a Set-Cookie header in an | To store state, the origin server includes a Set-Cookie header in an | |||
HTTP response. In subsequent requests, the user agent returns a | HTTP response. In subsequent requests, the user agent returns a | |||
Cookie request header to the origin server. The Cookie header | Cookie request header to the origin server. The Cookie header | |||
skipping to change at page 20, line 33 ¶ | skipping to change at page 20, line 33 ¶ | |||
o The cookie-path is a prefix of the request-path, and the last | o The cookie-path is a prefix of the request-path, and the last | |||
character of the cookie-path is %x2F ("/"). | character of the cookie-path is %x2F ("/"). | |||
o The cookie-path is a prefix of the request-path, and the first | o The cookie-path is a prefix of the request-path, and the first | |||
character of the request-path that is not included in the cookie- | character of the request-path that is not included in the cookie- | |||
path is a %x2F ("/") character. | path is a %x2F ("/") character. | |||
5.2. "Same-site" and "cross-site" Requests | 5.2. "Same-site" and "cross-site" Requests | |||
Two origins, A and B, are considered same-site if the following | Two origins are same-site if they satisfy the "same site" criteria | |||
algorithm returns true: | defined in [SAMESITE]. A request is "same-site" if the following | |||
criteria are true: | ||||
1. If A and B are both the same globally unique identifier, return | ||||
true. | ||||
2. If A and B are both scheme/host/port triples: | ||||
1. If A's scheme does not equal B's scheme, return false. | ||||
2. Let hostA be A's host, and hostB be B's host. | ||||
3. If hostA equals hostB and hostA's registrable domain is null, | ||||
return true. | ||||
4. If hostA's registrable domain equals hostB's registrable | 1. The request is not the result of a cross-site redirect. That is, | |||
domain and is non-null, return true. | the origin of every url in the request's url list is same-site | |||
with the request's current url's origin. | ||||
3. Return false. | 2. The request is not the result of a reload navigation triggered | |||
through a user interface element (as defined by the user agent; | ||||
e.g., a request triggered by the user clicking a refresh button | ||||
on a toolbar). | ||||
Note: The port component of the origins is not considered. | 3. The request's current url's origin is same-site with the | |||
request's client's "site for cookies" (which is an origin), or if | ||||
the request has no client or the request's client is null. | ||||
A request is "same-site" if its target's URI's origin is same-site | Requests which are the result of a reload navigation triggered | |||
with the request's client's "site for cookies" (which is an origin), | through a user interface element are same-site if the reloaded | |||
or if the request has no client. The request is otherwise "cross- | document was originally navigated to via a same-site request. A | |||
site". | request that is not "same-site" is instead "cross-site". | |||
The request's client's "site for cookies" is calculated depending | The request's client's "site for cookies" is calculated depending | |||
upon its client's type, as described in the following subsections: | upon its client's type, as described in the following subsections: | |||
5.2.1. Document-based requests | 5.2.1. Document-based requests | |||
The URI displayed in a user agent's address bar is the only security | The URI displayed in a user agent's address bar is the only security | |||
context directly exposed to users, and therefore the only signal | context directly exposed to users, and therefore the only signal | |||
users can reasonably rely upon to determine whether or not they trust | users can reasonably rely upon to determine whether or not they trust | |||
a particular website. The origin of that URI represents the context | a particular website. The origin of that URI represents the context | |||
skipping to change at page 21, line 35 ¶ | skipping to change at page 21, line 30 ¶ | |||
For a document displayed in a top-level browsing context, we can stop | For a document displayed in a top-level browsing context, we can stop | |||
here: the document's "site for cookies" is the top-level origin. | here: the document's "site for cookies" is the top-level origin. | |||
For documents which are displayed in nested browsing contexts, we | For documents which are displayed in nested browsing contexts, we | |||
need to audit the origins of each of a document's ancestor browsing | need to audit the origins of each of a document's ancestor browsing | |||
contexts' active documents in order to account for the "multiple- | contexts' active documents in order to account for the "multiple- | |||
nested scenarios" described in Section 4 of [RFC7034]. A document's | nested scenarios" described in Section 4 of [RFC7034]. A document's | |||
"site for cookies" is the top-level origin if and only if the top- | "site for cookies" is the top-level origin if and only if the top- | |||
level origin is same-site with the document's origin, and with each | level origin is same-site with the document's origin, and with each | |||
of the document's ancestor documents' origins. Otherwise its "site | of the document's ancestor documents' origins. Otherwise its "site | |||
for cookies" is an origin set to a globally unique identifier. | for cookies" is an origin set to an opaque origin. | |||
Given a Document ("document"), the following algorithm returns its | Given a Document ("document"), the following algorithm returns its | |||
"site for cookies": | "site for cookies": | |||
1. Let "top-document" be the active document in "document"'s | 1. Let "top-document" be the active document in "document"'s | |||
browsing context's top-level browsing context. | browsing context's top-level browsing context. | |||
2. Let "top-origin" be the origin of "top-document"'s URI if "top- | 2. Let "top-origin" be the origin of "top-document"'s URI if "top- | |||
document"'s sandboxed origin browsing context flag is set, and | document"'s sandboxed origin browsing context flag is set, and | |||
"top-document"'s origin otherwise. | "top-document"'s origin otherwise. | |||
skipping to change at page 22, line 10 ¶ | skipping to change at page 22, line 6 ¶ | |||
3. Let "documents" be a list containing "document" and each of | 3. Let "documents" be a list containing "document" and each of | |||
"document"'s ancestor browsing contexts' active documents. | "document"'s ancestor browsing contexts' active documents. | |||
4. For each "item" in "documents": | 4. For each "item" in "documents": | |||
1. Let "origin" be the origin of "item"'s URI if "item"'s | 1. Let "origin" be the origin of "item"'s URI if "item"'s | |||
sandboxed origin browsing context flag is set, and "item"'s | sandboxed origin browsing context flag is set, and "item"'s | |||
origin otherwise. | origin otherwise. | |||
2. If "origin" is not same-site with "top-origin", return an | 2. If "origin" is not same-site with "top-origin", return an | |||
origin set to a globally unique identifier. | origin set to an opaque origin. | |||
5. Return "top-origin". | 5. Return "top-origin". | |||
5.2.2. Worker-based requests | 5.2.2. Worker-based requests | |||
Worker-driven requests aren't as clear-cut as document-driven | Worker-driven requests aren't as clear-cut as document-driven | |||
requests, as there isn't a clear link between a top-level browsing | requests, as there isn't a clear link between a top-level browsing | |||
context and a worker. This is especially true for Service Workers | context and a worker. This is especially true for Service Workers | |||
[SERVICE-WORKERS], which may execute code in the background, without | [SERVICE-WORKERS], which may execute code in the background, without | |||
any document visible at all. | any document visible at all. | |||
skipping to change at page 22, line 37 ¶ | skipping to change at page 22, line 33 ¶ | |||
5.2.2.1. Dedicated and Shared Workers | 5.2.2.1. Dedicated and Shared Workers | |||
Dedicated workers are simple, as each dedicated worker is bound to | Dedicated workers are simple, as each dedicated worker is bound to | |||
one and only one document. Requests generated from a dedicated | one and only one document. Requests generated from a dedicated | |||
worker (via "importScripts", "XMLHttpRequest", "fetch()", etc) define | worker (via "importScripts", "XMLHttpRequest", "fetch()", etc) define | |||
their "site for cookies" as that document's "site for cookies". | their "site for cookies" as that document's "site for cookies". | |||
Shared workers may be bound to multiple documents at once. As it is | Shared workers may be bound to multiple documents at once. As it is | |||
quite possible for those documents to have distinct "site for | quite possible for those documents to have distinct "site for | |||
cookies" values, the worker's "site for cookies" will be an origin | cookies" values, the worker's "site for cookies" will be an origin | |||
set to a globally unique identifier in cases where the values are not | set to an opaque origin in cases where the values are not all same- | |||
all same-site with the worker's origin, and the worker's origin in | site with the worker's origin, and the worker's origin in cases where | |||
cases where the values agree. | the values agree. | |||
Given a WorkerGlobalScope ("worker"), the following algorithm returns | Given a WorkerGlobalScope ("worker"), the following algorithm returns | |||
its "site for cookies": | its "site for cookies": | |||
1. Let "site" be "worker"'s origin. | 1. Let "site" be "worker"'s origin. | |||
2. For each "document" in "worker"'s Documents: | 2. For each "document" in "worker"'s Documents: | |||
1. Let "document-site" be "document"'s "site for cookies" (as | 1. Let "document-site" be "document"'s "site for cookies" (as | |||
defined in Section 5.2.1). | defined in Section 5.2.1). | |||
2. If "document-site" is not same-site with "site", return an | 2. If "document-site" is not same-site with "site", return an | |||
origin set to a globally unique identifier. | origin set to an opaque origin. | |||
3. Return "site". | 3. Return "site". | |||
5.2.2.2. Service Workers | 5.2.2.2. Service Workers | |||
Service Workers are more complicated, as they act as a completely | Service Workers are more complicated, as they act as a completely | |||
separate execution context with only tangential relationship to the | separate execution context with only tangential relationship to the | |||
Document which registered them. | Document which registered them. | |||
Requests which simply pass through a Service Worker will be handled | Requests which simply pass through a Service Worker will be handled | |||
skipping to change at page 23, line 44 ¶ | skipping to change at page 23, line 42 ¶ | |||
Section 7.1). | Section 7.1). | |||
If the user agent does not ignore the Set-Cookie header field in its | If the user agent does not ignore the Set-Cookie header field in its | |||
entirety, the user agent MUST parse the field-value of the Set-Cookie | entirety, the user agent MUST parse the field-value of the Set-Cookie | |||
header field as a set-cookie-string (defined below). | header field as a set-cookie-string (defined below). | |||
NOTE: The algorithm below is more permissive than the grammar in | NOTE: The algorithm below is more permissive than the grammar in | |||
Section 4.1. For example, the algorithm strips leading and trailing | Section 4.1. For example, the algorithm strips leading and trailing | |||
whitespace from the cookie name and value (but maintains internal | whitespace from the cookie name and value (but maintains internal | |||
whitespace), whereas the grammar in Section 4.1 forbids whitespace in | whitespace), whereas the grammar in Section 4.1 forbids whitespace in | |||
these positions. User agents use this algorithm so as to | these positions. In addition, the algorithm below accommodates some | |||
interoperate with servers that do not follow the recommendations in | characters that are not cookie-octets according to the grammar in | |||
Section 4. | Section 4.1. User agents use this algorithm so as to interoperate | |||
with servers that do not follow the recommendations in Section 4. | ||||
NOTE: As set-cookie-string may originate from a non-HTTP API, it is | ||||
not guaranteed to be free of CTL characters, so this algorithm | ||||
handles them explicitly. | ||||
A user agent MUST use an algorithm equivalent to the following | A user agent MUST use an algorithm equivalent to the following | |||
algorithm to parse a set-cookie-string: | algorithm to parse a set-cookie-string: | |||
1. If the set-cookie-string contains a %x3B (";") character: | 1. If the set-cookie-string contains a %x0D (CR), %x0A (LF), or %x00 | |||
(NUL) octet, then set the set-cookie-string equal to all the | ||||
characters of set-cookie-string up to, but not including, the | ||||
first such octet. | ||||
2. If the set-cookie-string contains a %x00-1F / %x7F (CTL) | ||||
character: Abort these steps and ignore the set-cookie-string | ||||
entirely. | ||||
3. If the set-cookie-string contains a %x3B (";") character: | ||||
1. The name-value-pair string consists of the characters up to, | 1. The name-value-pair string consists of the characters up to, | |||
but not including, the first %x3B (";"), and the unparsed- | but not including, the first %x3B (";"), and the unparsed- | |||
attributes consist of the remainder of the set-cookie-string | attributes consist of the remainder of the set-cookie-string | |||
(including the %x3B (";") in question). | (including the %x3B (";") in question). | |||
Otherwise: | Otherwise: | |||
1. The name-value-pair string consists of all the characters | 1. The name-value-pair string consists of all the characters | |||
contained in the set-cookie-string, and the unparsed- | contained in the set-cookie-string, and the unparsed- | |||
attributes is the empty string. | attributes is the empty string. | |||
2. If the name-value-pair string lacks a %x3D ("=") character, then | 4. If the name-value-pair string lacks a %x3D ("=") character, then | |||
the name string is empty, and the value string is the value of | the name string is empty, and the value string is the value of | |||
name-value-pair. | name-value-pair. | |||
Otherwise, the name string consists of the characters up to, but | Otherwise, the name string consists of the characters up to, but | |||
not including, the first %x3D ("=") character, and the (possibly | not including, the first %x3D ("=") character, and the (possibly | |||
empty) value string consists of the characters after the first | empty) value string consists of the characters after the first | |||
%x3D ("=") character. | %x3D ("=") character. | |||
3. Remove any leading or trailing WSP characters from the name | 5. Remove any leading or trailing WSP characters from the name | |||
string and the value string. | string and the value string. | |||
4. The cookie-name is the name string, and the cookie-value is the | 6. The cookie-name is the name string, and the cookie-value is the | |||
value string. | value string. | |||
The user agent MUST use an algorithm equivalent to the following | The user agent MUST use an algorithm equivalent to the following | |||
algorithm to parse the unparsed-attributes: | algorithm to parse the unparsed-attributes: | |||
1. If the unparsed-attributes string is empty, skip the rest of | 1. If the unparsed-attributes string is empty, skip the rest of | |||
these steps. | these steps. | |||
2. Discard the first character of the unparsed-attributes (which | 2. Discard the first character of the unparsed-attributes (which | |||
will be a %x3B (";") character). | will be a %x3B (";") character). | |||
skipping to change at page 28, line 9 ¶ | skipping to change at page 28, line 15 ¶ | |||
3. If cookie-av's attribute-value is a case-insensitive match for | 3. If cookie-av's attribute-value is a case-insensitive match for | |||
"Strict", set "enforcement" to "Strict". | "Strict", set "enforcement" to "Strict". | |||
4. If cookie-av's attribute-value is a case-insensitive match for | 4. If cookie-av's attribute-value is a case-insensitive match for | |||
"Lax", set "enforcement" to "Lax". | "Lax", set "enforcement" to "Lax". | |||
5. Append an attribute to the cookie-attribute-list with an | 5. Append an attribute to the cookie-attribute-list with an | |||
attribute-name of "SameSite" and an attribute-value of | attribute-name of "SameSite" and an attribute-value of | |||
"enforcement". | "enforcement". | |||
Note: This algorithm maps the "None" value, as well as any unknown | ||||
value, to the "None" behavior, which is helpful for backwards | ||||
compatibility when introducing new variants. | ||||
5.3.7.1. "Strict" and "Lax" enforcement | 5.3.7.1. "Strict" and "Lax" enforcement | |||
Same-site cookies in "Strict" enforcement mode will not be sent along | Same-site cookies in "Strict" enforcement mode will not be sent along | |||
with top-level navigations which are triggered from a cross-site | with top-level navigations which are triggered from a cross-site | |||
document context. As discussed in Section 8.8.2, this might or might | document context. As discussed in Section 8.8.2, this might or might | |||
not be compatible with existing session management systems. In the | not be compatible with existing session management systems. In the | |||
interests of providing a drop-in mechanism that mitigates the risk of | interests of providing a drop-in mechanism that mitigates the risk of | |||
CSRF attacks, developers may set the "SameSite" attribute in a "Lax" | CSRF attacks, developers may set the "SameSite" attribute in a "Lax" | |||
enforcement mode that carves out an exception which sends same-site | enforcement mode that carves out an exception which sends same-site | |||
cookies along with cross-site requests if and only if they are top- | cookies along with cross-site requests if and only if they are top- | |||
skipping to change at page 29, line 17 ¶ | skipping to change at page 29, line 19 ¶ | |||
list, the user agent MUST process the cookie as follows: | list, the user agent MUST process the cookie as follows: | |||
1. A user agent MAY ignore a received cookie in its entirety. For | 1. A user agent MAY ignore a received cookie in its entirety. For | |||
example, the user agent might wish to block receiving cookies | example, the user agent might wish to block receiving cookies | |||
from "third-party" responses or the user agent might not wish to | from "third-party" responses or the user agent might not wish to | |||
store cookies that exceed some size. | store cookies that exceed some size. | |||
2. If cookie-name is empty and cookie-value is empty, abort these | 2. If cookie-name is empty and cookie-value is empty, abort these | |||
steps and ignore the cookie entirely. | steps and ignore the cookie entirely. | |||
3. Create a new cookie with name cookie-name, value cookie-value. | 3. If the cookie-name or the cookie-value contains a %x00-1F / %x7F | |||
(CTL) character, abort these steps and ignore the cookie | ||||
entirely. | ||||
4. Create a new cookie with name cookie-name, value cookie-value. | ||||
Set the creation-time and the last-access-time to the current | Set the creation-time and the last-access-time to the current | |||
date and time. | date and time. | |||
4. If the cookie-attribute-list contains an attribute with an | 5. If the cookie-attribute-list contains an attribute with an | |||
attribute-name of "Max-Age": | attribute-name of "Max-Age": | |||
1. Set the cookie's persistent-flag to true. | 1. Set the cookie's persistent-flag to true. | |||
2. Set the cookie's expiry-time to attribute-value of the last | 2. Set the cookie's expiry-time to attribute-value of the last | |||
attribute in the cookie-attribute-list with an attribute- | attribute in the cookie-attribute-list with an attribute- | |||
name of "Max-Age". | name of "Max-Age". | |||
Otherwise, if the cookie-attribute-list contains an attribute | Otherwise, if the cookie-attribute-list contains an attribute | |||
with an attribute-name of "Expires" (and does not contain an | with an attribute-name of "Expires" (and does not contain an | |||
skipping to change at page 29, line 47 ¶ | skipping to change at page 30, line 5 ¶ | |||
attribute in the cookie-attribute-list with an attribute- | attribute in the cookie-attribute-list with an attribute- | |||
name of "Expires". | name of "Expires". | |||
Otherwise: | Otherwise: | |||
1. Set the cookie's persistent-flag to false. | 1. Set the cookie's persistent-flag to false. | |||
2. Set the cookie's expiry-time to the latest representable | 2. Set the cookie's expiry-time to the latest representable | |||
date. | date. | |||
5. If the cookie-attribute-list contains an attribute with an | 6. If the cookie-attribute-list contains an attribute with an | |||
attribute-name of "Domain": | attribute-name of "Domain": | |||
1. Let the domain-attribute be the attribute-value of the last | 1. Let the domain-attribute be the attribute-value of the last | |||
attribute in the cookie-attribute-list with an attribute- | attribute in the cookie-attribute-list with an attribute- | |||
name of "Domain". | name of "Domain". | |||
Otherwise: | Otherwise: | |||
1. Let the domain-attribute be the empty string. | 1. Let the domain-attribute be the empty string. | |||
6. If the user agent is configured to reject "public suffixes" and | 7. If the user agent is configured to reject "public suffixes" and | |||
the domain-attribute is a public suffix: | the domain-attribute is a public suffix: | |||
1. If the domain-attribute is identical to the canonicalized | 1. If the domain-attribute is identical to the canonicalized | |||
request-host: | request-host: | |||
1. Let the domain-attribute be the empty string. | 1. Let the domain-attribute be the empty string. | |||
Otherwise: | Otherwise: | |||
1. Ignore the cookie entirely and abort these steps. | 1. Ignore the cookie entirely and abort these steps. | |||
NOTE: This step prevents "attacker.example" from disrupting the | NOTE: This step prevents "attacker.example" from disrupting the | |||
integrity of "site.example" by setting a cookie with a Domain | integrity of "site.example" by setting a cookie with a Domain | |||
attribute of "example". | attribute of "example". | |||
7. If the domain-attribute is non-empty: | 8. If the domain-attribute is non-empty: | |||
1. If the canonicalized request-host does not domain-match the | 1. If the canonicalized request-host does not domain-match the | |||
domain-attribute: | domain-attribute: | |||
1. Ignore the cookie entirely and abort these steps. | 1. Ignore the cookie entirely and abort these steps. | |||
Otherwise: | Otherwise: | |||
1. Set the cookie's host-only-flag to false. | 1. Set the cookie's host-only-flag to false. | |||
2. Set the cookie's domain to the domain-attribute. | 2. Set the cookie's domain to the domain-attribute. | |||
Otherwise: | Otherwise: | |||
1. Set the cookie's host-only-flag to true. | 1. Set the cookie's host-only-flag to true. | |||
2. Set the cookie's domain to the canonicalized request-host. | 2. Set the cookie's domain to the canonicalized request-host. | |||
8. If the cookie-attribute-list contains an attribute with an | 9. If the cookie-attribute-list contains an attribute with an | |||
attribute-name of "Path", set the cookie's path to attribute- | attribute-name of "Path", set the cookie's path to attribute- | |||
value of the last attribute in the cookie-attribute-list with an | value of the last attribute in the cookie-attribute-list with an | |||
attribute-name of "Path". Otherwise, set the cookie's path to | attribute-name of "Path". Otherwise, set the cookie's path to | |||
the default-path of the request-uri. | the default-path of the request-uri. | |||
9. If the cookie-attribute-list contains an attribute with an | 10. If the cookie-attribute-list contains an attribute with an | |||
attribute-name of "Secure", set the cookie's secure-only-flag to | attribute-name of "Secure", set the cookie's secure-only-flag to | |||
true. Otherwise, set the cookie's secure-only-flag to false. | true. Otherwise, set the cookie's secure-only-flag to false. | |||
10. If the scheme component of the request-uri does not denote a | 11. If the scheme component of the request-uri does not denote a | |||
"secure" protocol (as defined by the user agent), and the | "secure" protocol (as defined by the user agent), and the | |||
cookie's secure-only-flag is true, then abort these steps and | cookie's secure-only-flag is true, then abort these steps and | |||
ignore the cookie entirely. | ignore the cookie entirely. | |||
11. If the cookie-attribute-list contains an attribute with an | 12. If the cookie-attribute-list contains an attribute with an | |||
attribute-name of "HttpOnly", set the cookie's http-only-flag to | attribute-name of "HttpOnly", set the cookie's http-only-flag to | |||
true. Otherwise, set the cookie's http-only-flag to false. | true. Otherwise, set the cookie's http-only-flag to false. | |||
12. If the cookie was received from a "non-HTTP" API and the | 13. If the cookie was received from a "non-HTTP" API and the | |||
cookie's http-only-flag is true, abort these steps and ignore | cookie's http-only-flag is true, abort these steps and ignore | |||
the cookie entirely. | the cookie entirely. | |||
13. If the cookie's secure-only-flag is false, and the scheme | 14. If the cookie's secure-only-flag is false, and the scheme | |||
component of request-uri does not denote a "secure" protocol, | component of request-uri does not denote a "secure" protocol, | |||
then abort these steps and ignore the cookie entirely if the | then abort these steps and ignore the cookie entirely if the | |||
cookie store contains one or more cookies that meet all of the | cookie store contains one or more cookies that meet all of the | |||
following criteria: | following criteria: | |||
1. Their name matches the name of the newly-created cookie. | 1. Their name matches the name of the newly-created cookie. | |||
2. Their secure-only-flag is true. | 2. Their secure-only-flag is true. | |||
3. Their domain domain-matches the domain of the newly-created | 3. Their domain domain-matches the domain of the newly-created | |||
skipping to change at page 31, line 42 ¶ | skipping to change at page 31, line 49 ¶ | |||
of the existing cookie. | of the existing cookie. | |||
Note: The path comparison is not symmetric, ensuring only that a | Note: The path comparison is not symmetric, ensuring only that a | |||
newly-created, non-secure cookie does not overlay an existing | newly-created, non-secure cookie does not overlay an existing | |||
secure cookie, providing some mitigation against cookie-fixing | secure cookie, providing some mitigation against cookie-fixing | |||
attacks. That is, given an existing secure cookie named 'a' | attacks. That is, given an existing secure cookie named 'a' | |||
with a path of '/login', a non-secure cookie named 'a' could be | with a path of '/login', a non-secure cookie named 'a' could be | |||
set for a path of '/' or '/foo', but not for a path of '/login' | set for a path of '/' or '/foo', but not for a path of '/login' | |||
or '/login/en'. | or '/login/en'. | |||
14. If the cookie-attribute-list contains an attribute with an | 15. If the cookie-attribute-list contains an attribute with an | |||
attribute-name of "SameSite", and an attribute-value of | attribute-name of "SameSite", and an attribute-value of | |||
"Strict", "Lax", or "None", set the cookie's same-site-flag to | "Strict", "Lax", or "None", set the cookie's same-site-flag to | |||
the attribute-value of the last attribute in the cookie- | the attribute-value of the last attribute in the cookie- | |||
attribute-list with an attribute-name of "SameSite". Otherwise, | attribute-list with an attribute-name of "SameSite". Otherwise, | |||
set the cookie's same-site-flag to "Default". | set the cookie's same-site-flag to "Default". | |||
15. If the cookie's "same-site-flag" is not "None": | 16. If the cookie's "same-site-flag" is not "None": | |||
1. If the cookie was received from a "non-HTTP" API, and the | 1. If the cookie was received from a "non-HTTP" API, and the | |||
API was called from a browsing context's active document | API was called from a browsing context's active document | |||
whose "site for cookies" is not same-site with the top-level | whose "site for cookies" is not same-site with the top-level | |||
origin, then abort these steps and ignore the newly created | origin, then abort these steps and ignore the newly created | |||
cookie entirely. | cookie entirely. | |||
2. If the cookie was received from a "same-site" request (as | 2. If the cookie was received from a "same-site" request (as | |||
defined in Section 5.2), skip the remaining substeps and | defined in Section 5.2), skip the remaining substeps and | |||
continue processing the cookie. | continue processing the cookie. | |||
skipping to change at page 32, line 27 ¶ | skipping to change at page 32, line 35 ¶ | |||
processing the cookie. | processing the cookie. | |||
Note: Top-level navigations can create a cookie with any | Note: Top-level navigations can create a cookie with any | |||
"SameSite" value, even if the new cookie wouldn't have been | "SameSite" value, even if the new cookie wouldn't have been | |||
sent along with the request had it already existed prior to | sent along with the request had it already existed prior to | |||
the navigation. | the navigation. | |||
4. Abort these steps and ignore the newly created cookie | 4. Abort these steps and ignore the newly created cookie | |||
entirely. | entirely. | |||
16. If the cookie's "same-site-flag" is "None", abort these steps | 17. If the cookie's "same-site-flag" is "None", abort these steps | |||
and ignore the cookie entirely unless the cookie's secure-only- | and ignore the cookie entirely unless the cookie's secure-only- | |||
flag is true. | flag is true. | |||
17. If the cookie-name begins with a case-sensitive match for the | 18. If the cookie-name begins with a case-sensitive match for the | |||
string "__Secure-", abort these steps and ignore the cookie | string "__Secure-", abort these steps and ignore the cookie | |||
entirely unless the cookie's secure-only-flag is true. | entirely unless the cookie's secure-only-flag is true. | |||
18. If the cookie-name begins with a case-sensitive match for the | 19. If the cookie-name begins with a case-sensitive match for the | |||
string "__Host-", abort these steps and ignore the cookie | string "__Host-", abort these steps and ignore the cookie | |||
entirely unless the cookie meets all the following criteria: | entirely unless the cookie meets all the following criteria: | |||
1. The cookie's secure-only-flag is true. | 1. The cookie's secure-only-flag is true. | |||
2. The cookie's host-only-flag is true. | 2. The cookie's host-only-flag is true. | |||
3. The cookie-attribute-list contains an attribute with an | 3. The cookie-attribute-list contains an attribute with an | |||
attribute-name of "Path", and the cookie's path is "/". | attribute-name of "Path", and the cookie's path is "/". | |||
19. If the cookie store contains a cookie with the same name, | 20. If the cookie store contains a cookie with the same name, | |||
domain, host-only-flag, and path as the newly-created cookie: | domain, host-only-flag, and path as the newly-created cookie: | |||
1. Let old-cookie be the existing cookie with the same name, | 1. Let old-cookie be the existing cookie with the same name, | |||
domain, host-only-flag, and path as the newly-created | domain, host-only-flag, and path as the newly-created | |||
cookie. (Notice that this algorithm maintains the invariant | cookie. (Notice that this algorithm maintains the invariant | |||
that there is at most one such cookie.) | that there is at most one such cookie.) | |||
2. If the newly-created cookie was received from a "non-HTTP" | 2. If the newly-created cookie was received from a "non-HTTP" | |||
API and the old-cookie's http-only-flag is true, abort these | API and the old-cookie's http-only-flag is true, abort these | |||
steps and ignore the newly created cookie entirely. | steps and ignore the newly created cookie entirely. | |||
3. Update the creation-time of the newly-created cookie to | 3. Update the creation-time of the newly-created cookie to | |||
match the creation-time of the old-cookie. | match the creation-time of the old-cookie. | |||
4. Remove the old-cookie from the cookie store. | 4. Remove the old-cookie from the cookie store. | |||
20. Insert the newly-created cookie into the cookie store. | 21. Insert the newly-created cookie into the cookie store. | |||
A cookie is "expired" if the cookie has an expiry date in the past. | A cookie is "expired" if the cookie has an expiry date in the past. | |||
The user agent MUST evict all expired cookies from the cookie store | The user agent MUST evict all expired cookies from the cookie store | |||
if, at any time, an expired cookie exists in the cookie store. | if, at any time, an expired cookie exists in the cookie store. | |||
At any time, the user agent MAY "remove excess cookies" from the | At any time, the user agent MAY "remove excess cookies" from the | |||
cookie store if the number of cookies sharing a domain field exceeds | cookie store if the number of cookies sharing a domain field exceeds | |||
some implementation-defined upper bound (such as 50 cookies). | some implementation-defined upper bound (such as 50 cookies). | |||
skipping to change at page 43, line 27 ¶ | skipping to change at page 43, line 36 ¶ | |||
Setting the "SameSite" attribute in "strict" mode provides robust | Setting the "SameSite" attribute in "strict" mode provides robust | |||
defense in depth against CSRF attacks, but has the potential to | defense in depth against CSRF attacks, but has the potential to | |||
confuse users unless sites' developers carefully ensure that their | confuse users unless sites' developers carefully ensure that their | |||
cookie-based session management systems deal reasonably well with | cookie-based session management systems deal reasonably well with | |||
top-level navigations. | top-level navigations. | |||
Consider the scenario in which a user reads their email at MegaCorp | Consider the scenario in which a user reads their email at MegaCorp | |||
Inc's webmail provider "https://site.example/". They might expect | Inc's webmail provider "https://site.example/". They might expect | |||
that clicking on an emailed link to "https://projects.example/secret/ | that clicking on an emailed link to "https://projects.example/secret/ | |||
project" would show them the secret project that they're authorized | project" would show them the secret project that they're authorized | |||
to see, but if "projects.example" has marked their session cookies as | to see, but if "https://projects.example" has marked their session | |||
"SameSite", then this cross-site navigation won't send them along | cookies as "SameSite=Strict", then this cross-site navigation won't | |||
with the request. "projects.example" will render a 404 error to avoid | send them along with the request. "https://projects.example" will | |||
leaking secret information, and the user will be quite confused. | render a 404 error to avoid leaking secret information, and the user | |||
will be quite confused. | ||||
Developers can avoid this confusion by adopting a session management | Developers can avoid this confusion by adopting a session management | |||
system that relies on not one, but two cookies: one conceptually | system that relies on not one, but two cookies: one conceptually | |||
granting "read" access, another granting "write" access. The latter | granting "read" access, another granting "write" access. The latter | |||
could be marked as "SameSite", and its absence would prompt a | could be marked as "SameSite=Strict", and its absence would prompt a | |||
reauthentication step before executing any non-idempotent action. | reauthentication step before executing any non-idempotent action. | |||
The former could drop the "SameSite" attribute entirely, or choose | The former could be marked as "SameSite=Lax", in order to allow users | |||
the "Lax" version of enforcement, in order to allow users access to | access to data via top-level navigation, or "SameSite=None", to | |||
data via top-level navigation. | permit access in all contexts (including cross-site embedded | |||
contexts). | ||||
8.8.3. Mashups and Widgets | 8.8.3. Mashups and Widgets | |||
The "SameSite" attribute is inappropriate for some important use- | The "Lax" and "Strict" values for the "SameSite" attribute are | |||
cases. In particular, note that content intended for embedding in a | inappropriate for some important use-cases. In particular, note that | |||
cross-site contexts (social networking widgets or commenting | content intended for embedding in cross-site contexts (social | |||
services, for instance) will not have access to same-site cookies. | networking widgets or commenting services, for instance) will not | |||
Cookies may be required for requests triggered in these cross-site | have access to same-site cookies. Cookies which are required in | |||
contexts in order to provide seamless functionality that relies on a | these situations should be marked with "SameSite=None" to allow | |||
user's state. | access in cross-site contexts. | |||
Likewise, some forms of Single-Sign-On might require cookie-based | Likewise, some forms of Single-Sign-On might require cookie-based | |||
authentication in a cross-site context; these mechanisms will not | authentication in a cross-site context; these mechanisms will not | |||
function as intended with same-site cookies. | function as intended with same-site cookies and will also require | |||
"SameSite=None". | ||||
8.8.4. Server-controlled | 8.8.4. Server-controlled | |||
SameSite cookies in and of themselves don't do anything to address | SameSite cookies in and of themselves don't do anything to address | |||
the general privacy concerns outlined in Section 7.1 of [RFC6265]. | the general privacy concerns outlined in Section 7.1 of [RFC6265]. | |||
The "SameSite" attribute is set by the server, and serves to mitigate | The "SameSite" attribute is set by the server, and serves to mitigate | |||
the risk of certain kinds of attacks that the server is worried | the risk of certain kinds of attacks that the server is worried | |||
about. The user is not involved in this decision. Moreover, a | about. The user is not involved in this decision. Moreover, a | |||
number of side-channels exist which could allow a server to link | number of side-channels exist which could allow a server to link | |||
distinct requests even in the absence of cookies (for example, | distinct requests even in the absence of cookies (for example, | |||
connection and/or socket pooling between same-site and cross-site | connection and/or socket pooling between same-site and cross-site | |||
requests). | requests). | |||
8.8.5. Reload navigations | ||||
Requests issued for reloads triggered through user interface elements | ||||
(such as a refresh button on a toolbar) are same-site only if the | ||||
reloaded document was originally navigated to via a same-site | ||||
request. This differs from the handling of other reload navigations, | ||||
which are always same-site if top-level, since the source browsing | ||||
context's active document is precisely the document being reloaded. | ||||
This special handling of reloads triggered through a user interface | ||||
element avoids sending "SameSite" cookies on user-initiated reloads | ||||
if they were withheld on the original navigation (i.e., if the | ||||
initial navigation were cross-site). If the reload navigation were | ||||
instead considered same-site, and sent all the initially withheld | ||||
"SameSite" cookies, the security benefits of withholding the cookies | ||||
in the first place would be nullified. This is especially important | ||||
given that the absence of "SameSite" cookies withheld on a cross-site | ||||
navigation request may lead to visible site breakage, prompting the | ||||
user to trigger a reload. | ||||
For example, suppose the user clicks on a link from | ||||
"https://attacker.example/" to "https://victim.example/". This is a | ||||
cross-site request, so "SameSite=Strict" cookies are withheld. | ||||
Suppose this causes "https://victim.example/" to appear broken, | ||||
because the site only displays its sensitive content if a particular | ||||
"SameSite" cookie is present in the request. The user, frustrated by | ||||
the unexpectedly broken site, presses refresh on their browser's | ||||
toolbar. To now consider the reload request same-site and send the | ||||
initially withheld "SameSite" cookie would defeat the purpose of | ||||
withholding it in the first place, as the reload navigation triggered | ||||
through the user interface may replay the original (potentially | ||||
malicious) request. Thus, the reload request should be considered | ||||
cross-site, like the request that initially navigated to the page. | ||||
9. IANA Considerations | 9. IANA Considerations | |||
9.1. Cookie | 9.1. Cookie | |||
The permanent message header field registry (see [RFC3864]) needs to | The permanent message header field registry (see [RFC3864]) needs to | |||
be updated with the following registration: | be updated with the following registration: | |||
Header field name: Cookie | Header field name: Cookie | |||
Applicable protocol: http | Applicable protocol: http | |||
skipping to change at page 47, line 15 ¶ | skipping to change at page 48, line 15 ¶ | |||
[RFC7231] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer | [RFC7231] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer | |||
Protocol (HTTP/1.1): Semantics and Content", RFC 7231, | Protocol (HTTP/1.1): Semantics and Content", RFC 7231, | |||
DOI 10.17487/RFC7231, June 2014, | DOI 10.17487/RFC7231, June 2014, | |||
<https://www.rfc-editor.org/info/rfc7231>. | <https://www.rfc-editor.org/info/rfc7231>. | |||
[RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for | [RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for | |||
Writing an IANA Considerations Section in RFCs", BCP 26, | Writing an IANA Considerations Section in RFCs", BCP 26, | |||
RFC 8126, DOI 10.17487/RFC8126, June 2017, | RFC 8126, DOI 10.17487/RFC8126, June 2017, | |||
<https://www.rfc-editor.org/info/rfc8126>. | <https://www.rfc-editor.org/info/rfc8126>. | |||
[SAMESITE] | ||||
WHATWG, "HTML - Living Standard", January 2021, | ||||
<https://html.spec.whatwg.org/#same-site>. | ||||
[SERVICE-WORKERS] | [SERVICE-WORKERS] | |||
Russell, A., Song, J., and J. Archibald, "Service | Russell, A., Song, J., and J. Archibald, "Service | |||
Workers", n.d., <http://www.w3.org/TR/service-workers/>. | Workers", n.d., <http://www.w3.org/TR/service-workers/>. | |||
[USASCII] American National Standards Institute, "Coded Character | [USASCII] American National Standards Institute, "Coded Character | |||
Set -- 7-bit American Standard Code for Information | Set -- 7-bit American Standard Code for Information | |||
Interchange", ANSI X3.4, 1986. | Interchange", ANSI X3.4, 1986. | |||
10.2. Informative References | 10.2. Informative References | |||
skipping to change at page 50, line 39 ¶ | skipping to change at page 51, line 43 ¶ | |||
[32] https://github.com/httpwg/http-extensions/issues/1159 | [32] https://github.com/httpwg/http-extensions/issues/1159 | |||
[33] https://github.com/httpwg/http-extensions/issues/1234 | [33] https://github.com/httpwg/http-extensions/issues/1234 | |||
[34] https://github.com/httpwg/http-extensions/pull/1325 | [34] https://github.com/httpwg/http-extensions/pull/1325 | |||
[35] https://github.com/httpwg/http-extensions/pull/1323 | [35] https://github.com/httpwg/http-extensions/pull/1323 | |||
[36] https://github.com/httpwg/http-extensions/pull/1324 | [36] https://github.com/httpwg/http-extensions/pull/1324 | |||
[37] https://github.com/httpwg/http-extensions/pull/1384 | ||||
[38] https://github.com/httpwg/http-extensions/pull/1348 | ||||
[39] https://github.com/httpwg/http-extensions/pull/1416 | ||||
[40] https://github.com/httpwg/http-extensions/pull/1420 | ||||
Appendix A. Changes | Appendix A. Changes | |||
A.1. draft-ietf-httpbis-rfc6265bis-00 | A.1. draft-ietf-httpbis-rfc6265bis-00 | |||
o Port [RFC6265] to Markdown. No (intentional) normative changes. | o Port [RFC6265] to Markdown. No (intentional) normative changes. | |||
A.2. draft-ietf-httpbis-rfc6265bis-01 | A.2. draft-ietf-httpbis-rfc6265bis-01 | |||
o Fixes to formatting caused by mistakes in the initial port to | o Fixes to formatting caused by mistakes in the initial port to | |||
Markdown: | Markdown: | |||
skipping to change at page 53, line 29 ¶ | skipping to change at page 54, line 44 ¶ | |||
o Add a default enforcement value to the "same-site-flag", | o Add a default enforcement value to the "same-site-flag", | |||
equivalent to "SameSite=Lax": https://github.com/httpwg/http- | equivalent to "SameSite=Lax": https://github.com/httpwg/http- | |||
extensions/pull/1325 [34]. | extensions/pull/1325 [34]. | |||
o Require a Secure attribute for "SameSite=None": | o Require a Secure attribute for "SameSite=None": | |||
https://github.com/httpwg/http-extensions/pull/1323 [35]. | https://github.com/httpwg/http-extensions/pull/1323 [35]. | |||
o Consider scheme when running the same-site algorithm: | o Consider scheme when running the same-site algorithm: | |||
https://github.com/httpwg/http-extensions/pull/1324 [36]. | https://github.com/httpwg/http-extensions/pull/1324 [36]. | |||
A.9. draft-ietf-httpbis-rfc6265bis-08 | ||||
o Define "same-site" for reload navigation requests, e.g. those | ||||
triggered via user interface elements: https://github.com/httpwg/ | ||||
http-extensions/pull/1384 [37] | ||||
o Consider redirects when defining same-site: | ||||
https://github.com/httpwg/http-extensions/pull/1348 [38] | ||||
o Align on using HTML terminology for origins: | ||||
https://github.com/httpwg/http-extensions/pull/1416 [39] | ||||
o Modify cookie parsing and creation algorithms in Section 5.3 and | ||||
Section 5.4 to explicitly handle control characters: | ||||
https://github.com/httpwg/http-extensions/pull/1420 [40] | ||||
Acknowledgements | Acknowledgements | |||
RFC 6265 was written by Adam Barth. This document is a minor update | RFC 6265 was written by Adam Barth. This document is an update of | |||
of RFC 6265, adding small features, and aligning the specification | RFC 6265, adding features and aligning the specification with the | |||
with the reality of today's deployments. Here, we're standing upon | reality of today's deployments. Here, we're standing upon the | |||
the shoulders of a giant since the majority of the text is still | shoulders of a giant since the majority of the text is still Adam's. | |||
Adam's. | ||||
Authors' Addresses | Authors' Addresses | |||
Lily Chen (editor) | ||||
Google LLC | ||||
Email: chlily@google.com | ||||
Steven Englehardt (editor) | ||||
Mozilla | ||||
Email: senglehardt@mozilla.com | ||||
Mike West (editor) | Mike West (editor) | |||
Google, Inc | Google LLC | |||
Email: mkwst@google.com | Email: mkwst@google.com | |||
URI: https://mikewest.org/ | URI: https://mikewest.org/ | |||
John Wilander (editor) | John Wilander (editor) | |||
Apple, Inc | Apple, Inc | |||
Email: wilander@apple.com | Email: wilander@apple.com | |||
End of changes. 55 change blocks. | ||||
118 lines changed or deleted | 208 lines changed or added | |||
This html diff was produced by rfcdiff 1.44jr. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |