| draft-ietf-httpbis-rfc6265bis-06.txt | draft-ietf-httpbis-rfc6265bis-07.txt | |||
|---|---|---|---|---|
| HTTP M. West, Ed. | HTTP M. West, Ed. | |||
| Internet-Draft Google, Inc | Internet-Draft Google, Inc | |||
| Obsoletes: 6265 (if approved) J. Wilander, Ed. | Obsoletes: 6265 (if approved) J. Wilander, Ed. | |||
| Intended status: Standards Track Apple, Inc | Intended status: Standards Track Apple, Inc | |||
| Expires: October 22, 2020 April 20, 2020 | Expires: 10 June 2021 7 December 2020 | |||
| Cookies: HTTP State Management Mechanism | Cookies: HTTP State Management Mechanism | |||
| draft-ietf-httpbis-rfc6265bis-06 | draft-ietf-httpbis-rfc6265bis-07 | |||
| 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. | |||
| Note to Readers | Note to Readers | |||
| Discussion of this draft takes place on the HTTP working group | Discussion of this draft takes place on the HTTP working group | |||
| mailing list (ietf-http-wg@w3.org), which is archived at | mailing list (ietf-http-wg@w3.org), which is archived at | |||
| https://lists.w3.org/Archives/Public/ietf-http-wg/ [1]. | https://lists.w3.org/Archives/Public/ietf-http-wg/ | |||
| (https://lists.w3.org/Archives/Public/ietf-http-wg/). | ||||
| Working Group information can be found at http://httpwg.github.io/ | Working Group information can be found at http://httpwg.github.io/ | |||
| [2]; source code and issues list for this draft can be found at | (http://httpwg.github.io/); source code and issues list for this | |||
| https://github.com/httpwg/http-extensions/labels/6265bis [3]. | draft can be found at https://github.com/httpwg/http-extensions/ | |||
| labels/6265bis (https://github.com/httpwg/http-extensions/ | ||||
| labels/6265bis). | ||||
| Status of This Memo | Status of This Memo | |||
| This Internet-Draft is submitted in full conformance with the | This Internet-Draft is submitted in full conformance with the | |||
| provisions of BCP 78 and BCP 79. | provisions of BCP 78 and BCP 79. | |||
| 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 10 June 2021. | ||||
| This Internet-Draft will expire on October 22, 2020. | ||||
| Copyright Notice | Copyright Notice | |||
| Copyright (c) 2020 IETF Trust and the persons identified as the | Copyright (c) 2020 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/ | |||
| (https://trustee.ietf.org/license-info) in effect on the date of | license-info) in effect on the date of publication of this document. | |||
| publication of this document. Please review these documents | Please review these documents carefully, as they describe your rights | |||
| carefully, as they describe your rights and restrictions with respect | and restrictions with respect to this document. Code Components | |||
| to this document. Code Components extracted from this document must | extracted from this document must include Simplified BSD License text | |||
| include Simplified BSD License text as described in Section 4.e of | as described in Section 4.e of the Trust Legal Provisions and are | |||
| the Trust Legal Provisions and are provided without warranty as | provided without warranty as described in the Simplified BSD License. | |||
| described in the Simplified BSD License. | ||||
| This document may contain material from IETF Documents or IETF | This document may contain material from IETF Documents or IETF | |||
| Contributions published or made publicly available before November | Contributions published or made publicly available before November | |||
| 10, 2008. The person(s) controlling the copyright in some of this | 10, 2008. The person(s) controlling the copyright in some of this | |||
| material may not have granted the IETF Trust the right to allow | material may not have granted the IETF Trust the right to allow | |||
| modifications of such material outside the IETF Standards Process. | modifications of such material outside the IETF Standards Process. | |||
| Without obtaining an adequate license from the person(s) controlling | Without obtaining an adequate license from the person(s) controlling | |||
| the copyright in such materials, this document may not be modified | the copyright in such materials, this document may not be modified | |||
| outside the IETF Standards Process, and derivative works of it may | outside the IETF Standards Process, and derivative works of it may | |||
| not be created outside the IETF Standards Process, except to format | not be created outside the IETF Standards Process, except to format | |||
| skipping to change at page 2, line 52 ¶ | skipping to change at page 3, line 4 ¶ | |||
| 4.1. Set-Cookie . . . . . . . . . . . . . . . . . . . . . . . 9 | 4.1. Set-Cookie . . . . . . . . . . . . . . . . . . . . . . . 9 | |||
| 4.1.1. Syntax . . . . . . . . . . . . . . . . . . . . . . . 9 | 4.1.1. Syntax . . . . . . . . . . . . . . . . . . . . . . . 9 | |||
| 4.1.2. Semantics (Non-Normative) . . . . . . . . . . . . . . 11 | 4.1.2. Semantics (Non-Normative) . . . . . . . . . . . . . . 11 | |||
| 4.1.3. Cookie Name Prefixes . . . . . . . . . . . . . . . . 14 | 4.1.3. Cookie Name Prefixes . . . . . . . . . . . . . . . . 14 | |||
| 4.2. Cookie . . . . . . . . . . . . . . . . . . . . . . . . . 16 | 4.2. Cookie . . . . . . . . . . . . . . . . . . . . . . . . . 16 | |||
| 4.2.1. Syntax . . . . . . . . . . . . . . . . . . . . . . . 16 | 4.2.1. Syntax . . . . . . . . . . . . . . . . . . . . . . . 16 | |||
| 4.2.2. Semantics . . . . . . . . . . . . . . . . . . . . . . 16 | 4.2.2. Semantics . . . . . . . . . . . . . . . . . . . . . . 16 | |||
| 5. User Agent Requirements . . . . . . . . . . . . . . . . . . . 16 | 5. User Agent Requirements . . . . . . . . . . . . . . . . . . . 16 | |||
| 5.1. Subcomponent Algorithms . . . . . . . . . . . . . . . . . 17 | 5.1. Subcomponent Algorithms . . . . . . . . . . . . . . . . . 17 | |||
| 5.1.1. Dates . . . . . . . . . . . . . . . . . . . . . . . . 17 | 5.1.1. Dates . . . . . . . . . . . . . . . . . . . . . . . . 17 | |||
| 5.1.2. Canonicalized Host Names . . . . . . . . . . . . . . 19 | 5.1.2. Canonicalized Host Names . . . . . . . . . . . . . . 18 | |||
| 5.1.3. Domain Matching . . . . . . . . . . . . . . . . . . . 19 | 5.1.3. Domain Matching . . . . . . . . . . . . . . . . . . . 19 | |||
| 5.1.4. Paths and Path-Match . . . . . . . . . . . . . . . . 19 | 5.1.4. Paths and Path-Match . . . . . . . . . . . . . . . . 19 | |||
| 5.2. "Same-site" and "cross-site" Requests . . . . . . . . . . 20 | 5.2. "Same-site" and "cross-site" Requests . . . . . . . . . . 20 | |||
| 5.2.1. Document-based requests . . . . . . . . . . . . . . . 21 | 5.2.1. Document-based requests . . . . . . . . . . . . . . . 21 | |||
| 5.2.2. Worker-based requests . . . . . . . . . . . . . . . . 22 | 5.2.2. Worker-based requests . . . . . . . . . . . . . . . . 22 | |||
| 5.3. The Set-Cookie Header . . . . . . . . . . . . . . . . . . 23 | 5.3. The Set-Cookie Header . . . . . . . . . . . . . . . . . . 23 | |||
| 5.3.1. The Expires Attribute . . . . . . . . . . . . . . . . 25 | 5.3.1. The Expires Attribute . . . . . . . . . . . . . . . . 25 | |||
| 5.3.2. The Max-Age Attribute . . . . . . . . . . . . . . . . 26 | 5.3.2. The Max-Age Attribute . . . . . . . . . . . . . . . . 25 | |||
| 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 . . . . . . . . . . . . . . . . . 26 | |||
| 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 . . . . . . . . . . . . . . . . . . . . 33 | 5.5. The Cookie Header . . . . . . . . . . . . . . . . . . . . 33 | |||
| 6. Implementation Considerations . . . . . . . . . . . . . . . . 35 | 6. Implementation Considerations . . . . . . . . . . . . . . . . 36 | |||
| 6.1. Limits . . . . . . . . . . . . . . . . . . . . . . . . . 35 | 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 . . . . . . . . . . . . . . 36 | |||
| 7. Privacy Considerations . . . . . . . . . . . . . . . . . . . 36 | 7. Privacy Considerations . . . . . . . . . . . . . . . . . . . 37 | |||
| 7.1. Third-Party Cookies . . . . . . . . . . . . . . . . . . . 37 | 7.1. Third-Party Cookies . . . . . . . . . . . . . . . . . . . 37 | |||
| 7.2. User Controls . . . . . . . . . . . . . . . . . . . . . . 37 | 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 . . . . . . . . . . . . . . . . . . . . 38 | 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 . . . . . . . . . . . . . . . . . . 40 | 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 . . . . . . . . . . . . . . . . . . . . 42 | |||
| 8.8.1. Defense in depth . . . . . . . . . . . . . . . . . . 42 | 8.8.1. Defense in depth . . . . . . . . . . . . . . . . . . 43 | |||
| 8.8.2. Top-level Navigations . . . . . . . . . . . . . . . . 42 | 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 . . . . . . . . . . . . . . . . . . 43 | 8.8.4. Server-controlled . . . . . . . . . . . . . . . . . . 44 | |||
| 9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 44 | 9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 44 | |||
| 9.1. Cookie . . . . . . . . . . . . . . . . . . . . . . . . . 44 | 9.1. Cookie . . . . . . . . . . . . . . . . . . . . . . . . . 44 | |||
| 9.2. Set-Cookie . . . . . . . . . . . . . . . . . . . . . . . 44 | 9.2. Set-Cookie . . . . . . . . . . . . . . . . . . . . . . . 44 | |||
| 9.3. Cookie Attribute Registry . . . . . . . . . . . . . . . . 44 | 9.3. Cookie Attribute Registry . . . . . . . . . . . . . . . . 45 | |||
| 9.3.1. Procedure . . . . . . . . . . . . . . . . . . . . . . 44 | 9.3.1. Procedure . . . . . . . . . . . . . . . . . . . . . . 45 | |||
| 9.3.2. Registration . . . . . . . . . . . . . . . . . . . . 45 | 9.3.2. Registration . . . . . . . . . . . . . . . . . . . . 45 | |||
| 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 45 | 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 46 | |||
| 10.1. Normative References . . . . . . . . . . . . . . . . . . 45 | 10.1. Normative References . . . . . . . . . . . . . . . . . . 46 | |||
| 10.2. Informative References . . . . . . . . . . . . . . . . . 47 | 10.2. Informative References . . . . . . . . . . . . . . . . . 48 | |||
| 10.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 48 | Appendix A. Changes . . . . . . . . . . . . . . . . . . . . . . 49 | |||
| Appendix A. Changes . . . . . . . . . . . . . . . . . . . . . . 50 | A.1. draft-ietf-httpbis-rfc6265bis-00 . . . . . . . . . . . . 49 | |||
| A.1. draft-ietf-httpbis-rfc6265bis-00 . . . . . . . . . . . . 50 | ||||
| A.2. draft-ietf-httpbis-rfc6265bis-01 . . . . . . . . . . . . 50 | A.2. draft-ietf-httpbis-rfc6265bis-01 . . . . . . . . . . . . 50 | |||
| A.3. draft-ietf-httpbis-rfc6265bis-02 . . . . . . . . . . . . 50 | A.3. draft-ietf-httpbis-rfc6265bis-02 . . . . . . . . . . . . 50 | |||
| A.4. draft-ietf-httpbis-rfc6265bis-03 . . . . . . . . . . . . 51 | A.4. draft-ietf-httpbis-rfc6265bis-03 . . . . . . . . . . . . 51 | |||
| A.5. draft-ietf-httpbis-rfc6265bis-04 . . . . . . . . . . . . 51 | A.5. draft-ietf-httpbis-rfc6265bis-04 . . . . . . . . . . . . 51 | |||
| A.6. draft-ietf-httpbis-rfc6265bis-05 . . . . . . . . . . . . 52 | A.6. draft-ietf-httpbis-rfc6265bis-05 . . . . . . . . . . . . 52 | |||
| A.7. draft-ietf-httpbis-rfc6265bis-06 . . . . . . . . . . . . 52 | A.7. draft-ietf-httpbis-rfc6265bis-06 . . . . . . . . . . . . 52 | |||
| Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 52 | A.8. draft-ietf-httpbis-rfc6265bis-07 . . . . . . . . . . . . 52 | |||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 52 | Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 53 | |||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 53 | ||||
| 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 10, line 5 ¶ | skipping to change at page 10, line 5 ¶ | |||
| server to the user agent. | server to the user agent. | |||
| 4.1.1. Syntax | 4.1.1. Syntax | |||
| Informally, the Set-Cookie response header contains the header name | Informally, the Set-Cookie response header contains the header name | |||
| "Set-Cookie" followed by a ":" and a cookie. Each cookie begins with | "Set-Cookie" followed by a ":" and a cookie. Each cookie begins with | |||
| a name-value-pair, followed by zero or more attribute-value pairs. | a name-value-pair, followed by zero or more attribute-value pairs. | |||
| Servers SHOULD NOT send Set-Cookie headers that fail to conform to | Servers SHOULD NOT send Set-Cookie headers that fail to conform to | |||
| the following grammar: | the following grammar: | |||
| set-cookie-header = "Set-Cookie:" SP BWS set-cookie-string | set-cookie-header = "Set-Cookie:" SP BWS set-cookie-string | |||
| set-cookie-string = BWS cookie-pair *( BWS ";" OWS cookie-av ) | set-cookie-string = BWS cookie-pair *( BWS ";" OWS cookie-av ) | |||
| cookie-pair = cookie-name BWS "=" BWS cookie-value | cookie-pair = cookie-name BWS "=" BWS cookie-value | |||
| cookie-name = 1*cookie-octet | cookie-name = 1*cookie-octet | |||
| cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) | cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) | |||
| cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E / %x80-FF | cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E | |||
| ; US-ASCII characters excluding CTLs, | / %x80-FF | |||
| ; whitespace DQUOTE, comma, semicolon, | ; octets excluding CTLs, | |||
| ; and backslash | ; whitespace DQUOTE, comma, semicolon, | |||
| ; and backslash | ||||
| cookie-av = expires-av / max-age-av / domain-av / | cookie-av = expires-av / max-age-av / domain-av / | |||
| path-av / secure-av / httponly-av / | path-av / secure-av / httponly-av / | |||
| samesite-av / extension-av | samesite-av / extension-av | |||
| expires-av = "Expires" BWS "=" BWS sane-cookie-date | expires-av = "Expires" BWS "=" BWS sane-cookie-date | |||
| sane-cookie-date = | sane-cookie-date = | |||
| <IMF-fixdate, defined in [RFC7231], Section 7.1.1.1> | <IMF-fixdate, defined in [RFC7231], Section 7.1.1.1> | |||
| max-age-av = "Max-Age" BWS "=" BWS non-zero-digit *DIGIT | max-age-av = "Max-Age" BWS "=" BWS non-zero-digit *DIGIT | |||
| ; In practice, both expires-av and max-age-av | ; In practice, both expires-av and max-age-av | |||
| ; are limited to dates representable by the | ; are limited to dates representable by the | |||
| ; user agent. | ; user agent. | |||
| non-zero-digit = %x31-39 | non-zero-digit = %x31-39 | |||
| ; digits 1 through 9 | ; digits 1 through 9 | |||
| domain-av = "Domain" BWS "=" BWS domain-value | domain-av = "Domain" BWS "=" BWS domain-value | |||
| domain-value = <subdomain> | domain-value = <subdomain> | |||
| ; defined in [RFC1034], Section 3.5, as | ; defined in [RFC1034], Section 3.5, as | |||
| ; enhanced by [RFC1123], Section 2.1 | ; enhanced by [RFC1123], Section 2.1 | |||
| path-av = "Path" BWS "=" BWS path-value | path-av = "Path" BWS "=" BWS path-value | |||
| path-value = *av-octet | path-value = *av-octet | |||
| secure-av = "Secure" | secure-av = "Secure" | |||
| httponly-av = "HttpOnly" | httponly-av = "HttpOnly" | |||
| samesite-av = "SameSite" BWS "=" BWS samesite-value | samesite-av = "SameSite" BWS "=" BWS samesite-value | |||
| samesite-value = "Strict" / "Lax" / "None" | samesite-value = "Strict" / "Lax" / "None" | |||
| extension-av = *av-octet | extension-av = *av-octet | |||
| av-octet = %x20-3A / %x3C-7E | av-octet = %x20-3A / %x3C-7E | |||
| ; any CHAR except CTLs or ";" | ; any CHAR except CTLs or ";" | |||
| Note that some of the grammatical terms above reference documents | Note that some of the grammatical terms above reference documents | |||
| that use different grammatical notations than this document (which | that use different grammatical notations than this document (which | |||
| uses ABNF from [RFC5234]). | uses ABNF from [RFC5234]). | |||
| The semantics of the cookie-value are not defined by this document. | The semantics of the cookie-value are not defined by this document. | |||
| To maximize compatibility with user agents, servers that wish to | To maximize compatibility with user agents, servers that wish to | |||
| store arbitrary data in a cookie-value SHOULD encode that data, for | store arbitrary data in a cookie-value SHOULD encode that data, for | |||
| example, using Base64 [RFC4648]. | example, using Base64 [RFC4648]. | |||
| skipping to change at page 14, line 17 ¶ | skipping to change at page 14, line 22 ¶ | |||
| Note that the HttpOnly attribute is independent of the Secure | Note that the HttpOnly attribute is independent of the Secure | |||
| attribute: a cookie can have both the HttpOnly and the Secure | attribute: a cookie can have both the HttpOnly and the Secure | |||
| attribute. | attribute. | |||
| 4.1.2.7. The SameSite Attribute | 4.1.2.7. The SameSite Attribute | |||
| The "SameSite" attribute limits the scope of the cookie such that it | The "SameSite" attribute limits the scope of the cookie such that it | |||
| will only be attached to requests if those requests are same-site, as | will only be attached to requests if those requests are same-site, as | |||
| defined by the algorithm in Section 5.2. For example, requests for | defined by the algorithm in Section 5.2. For example, requests for | |||
| "https://site.example/sekrit-image" will attach same-site cookies if | "https://site.example/sekrit-image" will attach same-site cookies if | |||
| and only if initiated from a context whose "site for cookies" is | and only if initiated from a context whose "site for cookies" is an | |||
| "site.example". | origin with a scheme and registered domain of "https" and | |||
| "site.example" respectively. | ||||
| If the "SameSite" attribute's value is "Strict", the cookie will only | If the "SameSite" attribute's value is "Strict", the cookie will only | |||
| be sent along with "same-site" requests. If the value is "Lax", the | be sent along with "same-site" requests. If the value is "Lax", the | |||
| cookie will be sent with same-site requests, and with "cross-site" | cookie will be sent with same-site requests, and with "cross-site" | |||
| top-level navigations, as described in Section 5.3.7.1. If the value | top-level navigations, as described in Section 5.3.7.1. If the value | |||
| is "None", the cookie will be sent with same-site and cross-site | is "None", the cookie will be sent with same-site and cross-site | |||
| requests. If the "SameSite" attribute's value is something other | requests. If the "SameSite" attribute's value is something other | |||
| than these three known keywords, the attribute's value will be | than these three known keywords, the attribute's value will be | |||
| treated as "None". | subject to a default enforcement mode that is equivalent to "Lax". | |||
| The "SameSite" attribute affects cookie creation as well as delivery. | The "SameSite" attribute affects cookie creation as well as delivery. | |||
| Cookies which assert "SameSite=Lax" or "SameSite=Strict" cannot be | Cookies which assert "SameSite=Lax" or "SameSite=Strict" cannot be | |||
| set in responses to cross-site subresource requests, or cross-site | set in responses to cross-site subresource requests, or cross-site | |||
| nested navigations. They can be set along with any top-level | nested navigations. They can be set along with any top-level | |||
| navigation, cross-site or otherwise. | navigation, cross-site or otherwise. | |||
| 4.1.3. Cookie Name Prefixes | 4.1.3. Cookie Name Prefixes | |||
| Section 8.5 and Section 8.6 of this document spell out some of the | Section 8.5 and Section 8.6 of this document spell out some of the | |||
| skipping to change at page 15, line 47 ¶ | skipping to change at page 15, line 47 ¶ | |||
| continue to ignore. | continue to ignore. | |||
| For example, the following cookies would always be rejected: | For example, the following cookies would always be rejected: | |||
| Set-Cookie: __Host-SID=12345 | Set-Cookie: __Host-SID=12345 | |||
| Set-Cookie: __Host-SID=12345; Secure | Set-Cookie: __Host-SID=12345; Secure | |||
| Set-Cookie: __Host-SID=12345; Domain=site.example | Set-Cookie: __Host-SID=12345; Domain=site.example | |||
| Set-Cookie: __Host-SID=12345; Domain=site.example; Path=/ | Set-Cookie: __Host-SID=12345; Domain=site.example; Path=/ | |||
| Set-Cookie: __Host-SID=12345; Secure; Domain=site.example; Path=/ | Set-Cookie: __Host-SID=12345; Secure; Domain=site.example; Path=/ | |||
| While the would be accepted if set from a secure origin (e.g. | While the following would be accepted if set from a secure origin | |||
| "https://site.example/"), and rejected otherwise: | (e.g. "https://site.example/"), and rejected otherwise: | |||
| Set-Cookie: __Host-SID=12345; Secure; Path=/ | Set-Cookie: __Host-SID=12345; Secure; Path=/ | |||
| 4.2. Cookie | 4.2. Cookie | |||
| 4.2.1. Syntax | 4.2.1. Syntax | |||
| The user agent sends stored cookies to the origin server in the | The user agent sends stored cookies to the origin server in the | |||
| Cookie header. If the server conforms to the requirements in | Cookie header. If the server conforms to the requirements in | |||
| Section 4.1 (and the user agent conforms to the requirements in | Section 4.1 (and the user agent conforms to the requirements in | |||
| skipping to change at page 17, line 19 ¶ | skipping to change at page 17, line 19 ¶ | |||
| 5.1.1. Dates | 5.1.1. Dates | |||
| 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 a cookie-date. Note that the various boolean | algorithm to parse a cookie-date. Note that the various boolean | |||
| flags defined as a part of the algorithm (i.e., found-time, found- | flags defined as a part of the algorithm (i.e., found-time, found- | |||
| day-of-month, found-month, found-year) are initially "not set". | day-of-month, found-month, found-year) are initially "not set". | |||
| 1. Using the grammar below, divide the cookie-date into date-tokens. | 1. Using the grammar below, divide the cookie-date into date-tokens. | |||
| cookie-date = *delimiter date-token-list *delimiter | cookie-date = *delimiter date-token-list *delimiter | |||
| date-token-list = date-token *( 1*delimiter date-token ) | date-token-list = date-token *( 1*delimiter date-token ) | |||
| date-token = 1*non-delimiter | date-token = 1*non-delimiter | |||
| delimiter = %x09 / %x20-2F / %x3B-40 / %x5B-60 / %x7B-7E | delimiter = %x09 / %x20-2F / %x3B-40 / %x5B-60 / %x7B-7E | |||
| non-delimiter = %x00-08 / %x0A-1F / DIGIT / ":" / ALPHA / %x7F-FF | non-delimiter = %x00-08 / %x0A-1F / DIGIT / ":" / ALPHA / %x7F-FF | |||
| non-digit = %x00-2F / %x3A-FF | non-digit = %x00-2F / %x3A-FF | |||
| day-of-month = 1*2DIGIT [ non-digit *OCTET ] | day-of-month = 1*2DIGIT [ non-digit *OCTET ] | |||
| month = ( "jan" / "feb" / "mar" / "apr" / | month = ( "jan" / "feb" / "mar" / "apr" / | |||
| "may" / "jun" / "jul" / "aug" / | "may" / "jun" / "jul" / "aug" / | |||
| "sep" / "oct" / "nov" / "dec" ) *OCTET | "sep" / "oct" / "nov" / "dec" ) *OCTET | |||
| year = 2*4DIGIT [ non-digit *OCTET ] | year = 2*4DIGIT [ non-digit *OCTET ] | |||
| time = hms-time [ non-digit *OCTET ] | time = hms-time [ non-digit *OCTET ] | |||
| hms-time = time-field ":" time-field ":" time-field | hms-time = time-field ":" time-field ":" time-field | |||
| time-field = 1*2DIGIT | time-field = 1*2DIGIT | |||
| 2. Process each date-token sequentially in the order the date-tokens | 2. Process each date-token sequentially in the order the date-tokens | |||
| appear in the cookie-date: | appear in the cookie-date: | |||
| 1. If the found-time flag is not set and the token matches the | 1. If the found-time flag is not set and the token matches the | |||
| time production, set the found-time flag and set the hour- | time production, set the found-time flag and set the hour- | |||
| value, minute-value, and second-value to the numbers denoted | value, minute-value, and second-value to the numbers denoted | |||
| by the digits in the date-token, respectively. Skip the | by the digits in the date-token, respectively. Skip the | |||
| remaining sub-steps and continue to the next date-token. | remaining sub-steps and continue to the next date-token. | |||
| skipping to change at page 19, line 27 ¶ | skipping to change at page 19, line 22 ¶ | |||
| (see Section 6.3 of this specification). | (see Section 6.3 of this specification). | |||
| 3. Concatenate the resulting labels, separated by a %x2E (".") | 3. Concatenate the resulting labels, separated by a %x2E (".") | |||
| character. | character. | |||
| 5.1.3. Domain Matching | 5.1.3. Domain Matching | |||
| A string domain-matches a given domain string if at least one of the | A string domain-matches a given domain string if at least one of the | |||
| following conditions hold: | following conditions hold: | |||
| o The domain string and the string are identical. (Note that both | * The domain string and the string are identical. (Note that both | |||
| the domain string and the string will have been canonicalized to | the domain string and the string will have been canonicalized to | |||
| lower case at this point.) | lower case at this point.) | |||
| o All of the following conditions hold: | * All of the following conditions hold: | |||
| * The domain string is a suffix of the string. | - The domain string is a suffix of the string. | |||
| * The last character of the string that is not included in the | - The last character of the string that is not included in the | |||
| domain string is a %x2E (".") character. | domain string is a %x2E (".") character. | |||
| * The string is a host name (i.e., not an IP address). | - The string is a host name (i.e., not an IP address). | |||
| 5.1.4. Paths and Path-Match | 5.1.4. Paths and Path-Match | |||
| The user agent MUST use an algorithm equivalent to the following | The user agent MUST use an algorithm equivalent to the following | |||
| algorithm to compute the default-path of a cookie: | algorithm to compute the default-path of a cookie: | |||
| 1. Let uri-path be the path portion of the request-uri if such a | 1. Let uri-path be the path portion of the request-uri if such a | |||
| portion exists (and empty otherwise). For example, if the | portion exists (and empty otherwise). For example, if the | |||
| request-uri contains just a path (and optional query string), | request-uri contains just a path (and optional query string), | |||
| then the uri-path is that path (without the %x3F ("?") character | then the uri-path is that path (without the %x3F ("?") character | |||
| skipping to change at page 20, line 18 ¶ | skipping to change at page 20, line 11 ¶ | |||
| 3. If the uri-path contains no more than one %x2F ("/") character, | 3. If the uri-path contains no more than one %x2F ("/") character, | |||
| output %x2F ("/") and skip the remaining step. | output %x2F ("/") and skip the remaining step. | |||
| 4. Output the characters of the uri-path from the first character up | 4. Output the characters of the uri-path from the first character up | |||
| to, but not including, the right-most %x2F ("/"). | to, but not including, the right-most %x2F ("/"). | |||
| A request-path path-matches a given cookie-path if at least one of | A request-path path-matches a given cookie-path if at least one of | |||
| the following conditions holds: | the following conditions holds: | |||
| o The cookie-path and the request-path are identical. | * The cookie-path and the request-path are identical. | |||
| Note that this differs from the rules in [RFC3986] for equivalence | Note that this differs from the rules in [RFC3986] for equivalence | |||
| of the path component, and hence two equivalent paths can have | of the path component, and hence two equivalent paths can have | |||
| different cookies. | different cookies. | |||
| o The cookie-path is a prefix of the request-path, and the last | * 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 | * 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 | |||
| A request is "same-site" if its target's URI's origin's registrable | Two origins, A and B, are considered same-site if the following | |||
| domain is an exact match for the request's client's "site for | algorithm returns true: | |||
| cookies", or if the request has no client. The request is otherwise | ||||
| "cross-site". | ||||
| For a given request ("request"), the following algorithm returns | 1. If A and B are both the same globally unique identifier, return | |||
| "same-site" or "cross-site": | true. | |||
| 1. If "request"'s client is "null", return "same-site". | 2. If A and B are both scheme/host/port triples: | |||
| Note that this is the case for navigation triggered by the user | 1. If A's scheme does not equal B's scheme, return false. | |||
| directly (e.g. by typing directly into a user agent's address | ||||
| bar). | ||||
| 2. Let "site" be "request"'s client's "site for cookies" (as defined | 2. Let hostA be A's host, and hostB be B's host. | |||
| in the following sections). | ||||
| 3. Let "target" be the registrable domain of "request"'s current | 3. If hostA equals hostB and hostA's registrable domain is null, | |||
| url. | return true. | |||
| 4. If "site" is an exact match for "target", return "same-site". | 4. If hostA's registrable domain equals hostB's registrable | |||
| domain and is non-null, return true. | ||||
| 5. Return "cross-site". | 3. Return false. | |||
| Note: The port component of the origins is not considered. | ||||
| A request is "same-site" if its target's URI'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. The request is otherwise "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 registrable domain of that URI's origin | a particular website. The origin of that URI represents the context | |||
| represents the context in which a user most likely believes | in which a user most likely believes themselves to be interacting. | |||
| themselves to be interacting. We'll label this domain the "top-level | We'll define this origin, the top-level browsing context's active | |||
| site". | document's origin, as the "top-level origin". | |||
| 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 site. | 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 site if and only if the document | "site for cookies" is the top-level origin if and only if the top- | |||
| and each of its ancestor documents' origins have the same registrable | level origin is same-site with the document's origin, and with each | |||
| domain as the top-level site. Otherwise its "site for cookies" is | of the document's ancestor documents' origins. Otherwise its "site | |||
| the empty string. | for cookies" is an origin set to a globally unique identifier. | |||
| Given a Document ("document"), the following algorithm returns its | Given a Document ("document"), the following algorithm returns its | |||
| "site for cookies" (either a registrable domain, or the empty | "site for cookies": | |||
| string): | ||||
| 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. | |||
| 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"'s host's registrable domain is not an exact match | 2. If "origin" is not same-site with "top-origin", return an | |||
| for "top-origin"'s host's registrable domain, return the | origin set to a globally unique identifier. | |||
| empty string. | ||||
| 5. Return "top-origin"'s host's registrable domain. | 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. | |||
| Note: The descriptions below assume that workers must be same-origin | Note: The descriptions below assume that workers must be same-origin | |||
| skipping to change at page 22, line 32 ¶ | skipping to change at page 22, line 26 ¶ | |||
| determining their status. | determining their status. | |||
| 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 cookie" | quite possible for those documents to have distinct "site for | |||
| values, the worker's "site for cookies" will be the empty string in | cookies" values, the worker's "site for cookies" will be an origin | |||
| cases where the values diverge, and the shared value in cases where | set to a globally unique identifier in cases where the values are not | |||
| the values agree. | all same-site with the worker's origin, and the worker's origin in | |||
| cases where the values agree. | ||||
| Given a WorkerGlobalScope ("worker"), the following algorithm returns | Given a WorkerGlobalScope ("worker"), the following algorithm returns | |||
| its "site for cookies" (either a registrable domain, or the empty | its "site for cookies": | |||
| string): | ||||
| 1. Let "site" be "worker"'s origin's host's registrable domain. | 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 an exact match for "site", return | 2. If "document-site" is not same-site with "site", return an | |||
| the empty string. | origin set to a globally unique identifier. | |||
| 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 | |||
| as described above: the request's client will be the Document or | as described above: the request's client will be the Document or | |||
| Worker which initiated the request, and its "site for cookies" will | Worker which initiated the request, and its "site for cookies" will | |||
| be those defined in Section 5.2.1 and Section 5.2.2.1 | be those defined in Section 5.2.1 and Section 5.2.2.1 | |||
| Requests which are initiated by the Service Worker itself (via a | Requests which are initiated by the Service Worker itself (via a | |||
| direct call to "fetch()", for instance), on the other hand, will have | direct call to "fetch()", for instance), on the other hand, will have | |||
| a client which is a ServiceWorkerGlobalScope. Its "site for cookies" | a client which is a ServiceWorkerGlobalScope. Its "site for cookies" | |||
| will be the registrable domain of the Service Worker's URI. | will be the Service Worker's URI's origin. | |||
| Given a ServiceWorkerGlobalScope ("worker"), the following algorithm | Given a ServiceWorkerGlobalScope ("worker"), the following algorithm | |||
| returns its "site for cookies" (either a registrable domain, or the | returns its "site for cookies": | |||
| empty string): | ||||
| 1. Return "worker"'s origin's host's registrable domain. | 1. Return "worker"'s origin. | |||
| 5.3. The Set-Cookie Header | 5.3. The Set-Cookie Header | |||
| When a user agent receives a Set-Cookie header field in an HTTP | When a user agent receives a Set-Cookie header field in an HTTP | |||
| response, the user agent MAY ignore the Set-Cookie header field in | response, the user agent MAY ignore the Set-Cookie header field in | |||
| its entirety. For example, the user agent might wish to block | its entirety. For example, the user agent might wish to block | |||
| responses to "third-party" requests from setting cookies (see | responses to "third-party" requests from setting cookies (see | |||
| 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 | |||
| skipping to change at page 24, line 28 ¶ | skipping to change at page 24, line 21 ¶ | |||
| 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 | 3. Remove any leading or trailing WSP characters from the name | |||
| string and the value string. | string and the value string. | |||
| 4. If both the name string and the value string are empty, ignore | 4. The cookie-name is the name string, and the cookie-value is the | |||
| the set-cookie-string entirely. | ||||
| 5. 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 27, line 40 ¶ | skipping to change at page 27, line 30 ¶ | |||
| If the attribute-name case-insensitively matches the string | If the attribute-name case-insensitively matches the string | |||
| "HttpOnly", the user agent MUST append an attribute to the cookie- | "HttpOnly", the user agent MUST append an attribute to the cookie- | |||
| attribute-list with an attribute-name of HttpOnly and an empty | attribute-list with an attribute-name of HttpOnly and an empty | |||
| attribute-value. | attribute-value. | |||
| 5.3.7. The SameSite Attribute | 5.3.7. The SameSite Attribute | |||
| If the attribute-name case-insensitively matches the string | If the attribute-name case-insensitively matches the string | |||
| "SameSite", the user agent MUST process the cookie-av as follows: | "SameSite", the user agent MUST process the cookie-av as follows: | |||
| 1. Let "enforcement" be "None". | 1. Let "enforcement" be "Default". | |||
| 2. If cookie-av's attribute-value is a case-insensitive match for | 2. If cookie-av's attribute-value is a case-insensitive match for | |||
| "Strict", set "enforcement" to "Strict". | "None", set "enforcement" to "None". | |||
| 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". | ||||
| 4. If cookie-av's attribute-value is a case-insensitive match for | ||||
| "Lax", set "enforcement" to "Lax". | "Lax", set "enforcement" to "Lax". | |||
| 4. 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 | Note: This algorithm maps the "None" value, as well as any unknown | |||
| value, to the "None" behavior, which is helpful for backwards | value, to the "None" behavior, which is helpful for backwards | |||
| compatibility when introducing new variants. | 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- | |||
| level navigations which use a "safe" (in the [RFC7231] sense) HTTP | level navigations which use a "safe" (in the [RFC7231] sense) HTTP | |||
| method. | method. (Note that a request's method may be changed from POST to | |||
| GET for some redirects (see sections 6.4.2 and 6.4.3 of [RFC7231]); | ||||
| in these cases, a request's "safe"ness is determined based on the | ||||
| method of the current redirect hop.) | ||||
| Lax enforcement provides reasonable defense in depth against CSRF | Lax enforcement provides reasonable defense in depth against CSRF | |||
| attacks that rely on unsafe HTTP methods (like "POST"), but does not | attacks that rely on unsafe HTTP methods (like "POST"), but does not | |||
| offer a robust defense against CSRF as a general category of attack: | offer a robust defense against CSRF as a general category of attack: | |||
| 1. Attackers can still pop up new windows or trigger top-level | 1. Attackers can still pop up new windows or trigger top-level | |||
| navigations in order to create a "same-site" request (as | navigations in order to create a "same-site" request (as | |||
| described in Section 5.2.1), which is only a speedbump along the | described in Section 5.2.1), which is only a speedbump along the | |||
| road to exploitation. | road to exploitation. | |||
| skipping to change at page 29, line 7 ¶ | skipping to change at page 29, line 5 ¶ | |||
| When the user agent "receives a cookie" from a request-uri with name | When the user agent "receives a cookie" from a request-uri with name | |||
| cookie-name, value cookie-value, and attributes cookie-attribute- | cookie-name, value cookie-value, and attributes cookie-attribute- | |||
| 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. Create a new cookie with name cookie-name, value cookie-value. | 2. If cookie-name is empty and cookie-value is empty, abort these | |||
| steps and ignore the cookie entirely. | ||||
| 3. 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. | |||
| 3. If the cookie-attribute-list contains an attribute with an | 4. 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 37 ¶ | skipping to change at page 29, line 38 ¶ | |||
| 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. | |||
| 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 "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. | |||
| 5. If the user agent is configured to reject "public suffixes" and | 6. 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". | |||
| 6. If the domain-attribute is non-empty: | 7. 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. | |||
| 7. If the cookie-attribute-list contains an attribute with an | 8. 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. | |||
| 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 "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. | |||
| 9. If the scheme component of the request-uri does not denote a | 10. 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. | |||
| 10. If the cookie-attribute-list contains an attribute with an | 11. 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. | |||
| 11. If the cookie was received from a "non-HTTP" API and the | 12. 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. | |||
| 12. If the cookie's secure-only-flag is false, and the scheme | 13. 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 37 ¶ | skipping to change at page 31, line 37 ¶ | |||
| 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'. | |||
| 13. If the cookie-attribute-list contains an attribute with an | 14. If the cookie-attribute-list contains an attribute with an | |||
| attribute-name of "SameSite", set the cookie's same-site-flag to | attribute-name of "SameSite", and an attribute-value of | |||
| "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" (i.e. either | attribute-list with an attribute-name of "SameSite". Otherwise, | |||
| "Strict", "Lax", or "None"). Otherwise, set the cookie's same- | set the cookie's same-site-flag to "Default". | |||
| site-flag to "None". | ||||
| 14. If the cookie's "same-site-flag" is not "None": | 15. 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 context whose "site for cookies" is | API was called from a browsing context's active document | |||
| not an exact match for request-uri's host's registrable | whose "site for cookies" is not same-site with the top-level | |||
| domain, 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. | |||
| 3. If the cookie was received from a request which is | 3. If the cookie was received from a request which is | |||
| navigating a top-level browsing context [HTML] (e.g. if the | navigating a top-level browsing context [HTML] (e.g. if the | |||
| request's "reserved client" is either "null" or an | request's "reserved client" is either "null" or an | |||
| environment whose "target browsing context" is a top-level | environment whose "target browsing context" is a top-level | |||
| skipping to change at page 32, line 24 ¶ | skipping to change at page 32, line 24 ¶ | |||
| 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. | |||
| 15. If the cookie-name begins with a case-sensitive match for the | 16. If the cookie's "same-site-flag" is "None", abort these steps | |||
| and ignore the cookie entirely unless the cookie's secure-only- | ||||
| flag is true. | ||||
| 17. 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. | |||
| 16. 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 "__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 "/". | |||
| 17. If the cookie store contains a cookie with the same name, | 19. 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. | |||
| 18. Insert the newly-created cookie into the cookie store. | 20. 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 34, line 18 ¶ | skipping to change at page 34, line 25 ¶ | |||
| The user agent MUST use an algorithm equivalent to the following | The user agent MUST use an algorithm equivalent to the following | |||
| algorithm to compute the cookie-string from a cookie store and a | algorithm to compute the cookie-string from a cookie store and a | |||
| request-uri: | request-uri: | |||
| 1. Let cookie-list be the set of cookies from the cookie store that | 1. Let cookie-list be the set of cookies from the cookie store that | |||
| meets all of the following requirements: | meets all of the following requirements: | |||
| * Either: | * Either: | |||
| + The cookie's host-only-flag is true and the canonicalized | - The cookie's host-only-flag is true and the canonicalized | |||
| request-host is identical to the cookie's domain. | request-host is identical to the cookie's domain. | |||
| Or: | Or: | |||
| + The cookie's host-only-flag is false and the canonicalized | - The cookie's host-only-flag is false and the canonicalized | |||
| request-host domain-matches the cookie's domain. | request-host domain-matches the cookie's domain. | |||
| * The request-uri's path path-matches the cookie's path. | * The request-uri's path path-matches the cookie's path. | |||
| * If the cookie's secure-only-flag is true, then the request- | * If the cookie's secure-only-flag is true, then the request- | |||
| uri's scheme must denote a "secure" protocol (as defined by | uri's scheme must denote a "secure" protocol (as defined by | |||
| the user agent). | the user agent). | |||
| NOTE: The notion of a "secure" protocol is not defined by this | NOTE: The notion of a "secure" protocol is not defined by this | |||
| document. Typically, user agents consider a protocol secure | document. Typically, user agents consider a protocol secure | |||
| skipping to change at page 34, line 46 ¶ | skipping to change at page 35, line 5 ¶ | |||
| be a scheme that denotes a secure protocol. | be a scheme that denotes a secure protocol. | |||
| * If the cookie's http-only-flag is true, then exclude the | * If the cookie's http-only-flag is true, then exclude the | |||
| cookie if the cookie-string is being generated for a "non- | cookie if the cookie-string is being generated for a "non- | |||
| HTTP" API (as defined by the user agent). | HTTP" API (as defined by the user agent). | |||
| * If the cookie's same-site-flag is not "None", and the HTTP | * If the cookie's same-site-flag is not "None", and the HTTP | |||
| request is cross-site (as defined in Section 5.2) then exclude | request is cross-site (as defined in Section 5.2) then exclude | |||
| the cookie unless all of the following statements hold: | the cookie unless all of the following statements hold: | |||
| 1. The same-site-flag is "Lax" | 1. The same-site-flag is "Lax" or "Default". | |||
| 2. The HTTP request's method is "safe". | 2. The HTTP request's method is "safe". | |||
| 3. The HTTP request's target browsing context is a top-level | 3. The HTTP request's target browsing context is a top-level | |||
| browsing context. | browsing context. | |||
| 2. The user agent SHOULD sort the cookie-list in the following | 2. The user agent SHOULD sort the cookie-list in the following | |||
| order: | order: | |||
| * Cookies with longer paths are listed before cookies with | * Cookies with longer paths are listed before cookies with | |||
| skipping to change at page 35, line 51 ¶ | skipping to change at page 36, line 13 ¶ | |||
| octets is valid UTF-8. | octets is valid UTF-8. | |||
| 6. Implementation Considerations | 6. Implementation Considerations | |||
| 6.1. Limits | 6.1. Limits | |||
| Practical user agent implementations have limits on the number and | Practical user agent implementations have limits on the number and | |||
| size of cookies that they can store. General-use user agents SHOULD | size of cookies that they can store. General-use user agents SHOULD | |||
| provide each of the following minimum capabilities: | provide each of the following minimum capabilities: | |||
| o At least 4096 bytes per cookie (as measured by the sum of the | * At least 4096 bytes per cookie (as measured by the sum of the | |||
| length of the cookie's name, value, and attributes). | length of the cookie's name, value, and attributes). | |||
| o At least 50 cookies per domain. | * At least 50 cookies per domain. | |||
| o At least 3000 cookies total. | * At least 3000 cookies total. | |||
| Servers SHOULD use as few and as small cookies as possible to avoid | Servers SHOULD use as few and as small cookies as possible to avoid | |||
| reaching these implementation limits and to minimize network | reaching these implementation limits and to minimize network | |||
| bandwidth due to the Cookie header being included in every request. | bandwidth due to the Cookie header being included in every request. | |||
| Servers SHOULD gracefully degrade if the user agent fails to return | Servers SHOULD gracefully degrade if the user agent fails to return | |||
| one or more cookies in the Cookie header because the user agent might | one or more cookies in the Cookie header because the user agent might | |||
| evict any cookie at any time on orders from the user. | evict any cookie at any time on orders from the user. | |||
| 6.2. Application Programming Interfaces | 6.2. Application Programming Interfaces | |||
| skipping to change at page 44, line 41 ¶ | skipping to change at page 45, line 19 ¶ | |||
| Status: standard | Status: standard | |||
| Author/Change controller: IETF | Author/Change controller: IETF | |||
| Specification document: this specification (Section 5.3) | Specification document: this specification (Section 5.3) | |||
| 9.3. Cookie Attribute Registry | 9.3. Cookie Attribute Registry | |||
| The "Cookie Attribute Registry" defines the name space of attribute | The "Cookie Attribute Registry" defines the name space of attribute | |||
| used to control cookies' behavior. The registry is maintained at | used to control cookies' behavior. The registry is maintained at | |||
| https://www.iana.org/assignments/cookie-attribute-names [4]. | https://www.iana.org/assignments/cookie-attribute-names | |||
| (https://www.iana.org/assignments/cookie-attribute-names). | ||||
| 9.3.1. Procedure | 9.3.1. Procedure | |||
| Each registered attribute name is associated with a description, and | Each registered attribute name is associated with a description, and | |||
| a reference detailing how the attribute is to be processed and | a reference detailing how the attribute is to be processed and | |||
| stored. | stored. | |||
| New registrations happen on a "RFC Required" basis (see Section 4.7 | New registrations happen on a "RFC Required" basis (see Section 4.7 | |||
| of [RFC8126]). The attribute to be registered MUST match the | of [RFC8126]). The attribute to be registered MUST match the | |||
| "extension-av" syntax defined in Section 4.1.1. Note that attribute | "extension-av" syntax defined in Section 4.1.1. Note that attribute | |||
| names are generally defined in CamelCase, but technically accepted | names are generally defined in CamelCase, but technically accepted | |||
| case-insensitively. | case-insensitively. | |||
| 9.3.2. Registration | 9.3.2. Registration | |||
| The "Cookie Attribute Registry" will be updated with the | The "Cookie Attribute Registry" will be updated with the | |||
| registrations below: | registrations below: | |||
| +----------+----------------------------------------+ | +==========+==================================+ | |||
| | Name | Reference | | | Name | Reference | | |||
| +----------+----------------------------------------+ | +==========+==================================+ | |||
| | Domain | Section 4.1.2.3 of this document | | | Domain | Section 4.1.2.3 of this document | | |||
| | Expires | Section 4.1.2.1 of this document | | +----------+----------------------------------+ | |||
| | HttpOnly | {{attribute-httponly} of this document | | | Expires | Section 4.1.2.1 of this document | | |||
| | Max-Age | {{attribute-max-age} of this document | | +----------+----------------------------------+ | |||
| | Path | {{attribute-path} of this document | | | HttpOnly | Section 4.1.2.6 of this document | | |||
| | SameSite | {{attribute-samesite} of this document | | +----------+----------------------------------+ | |||
| | Secure | {{attribute-secure} of this document | | | Max-Age | Section 4.1.2.2 of this document | | |||
| +----------+----------------------------------------+ | +----------+----------------------------------+ | |||
| | Path | Section 4.1.2.4 of this document | | ||||
| +----------+----------------------------------+ | ||||
| | SameSite | Section 4.1.2.7 of this document | | ||||
| +----------+----------------------------------+ | ||||
| | Secure | Section 4.1.2.5 of this document | | ||||
| +----------+----------------------------------+ | ||||
| Table 1 | ||||
| 10. References | 10. References | |||
| 10.1. Normative References | 10.1. Normative References | |||
| [FETCH] van Kesteren, A., "Fetch", n.d., | [FETCH] van Kesteren, A., "Fetch", n.d., | |||
| <https://fetch.spec.whatwg.org/>. | <https://fetch.spec.whatwg.org/>. | |||
| [HTML] Hickson, I., Pieters, S., van Kesteren, A., Jaegenstedt, | [HTML] Hickson, I., Pieters, S., van Kesteren, A., Jägenstedt, | |||
| P., and D. Denicola, "HTML", n.d., | P., and D. Denicola, "HTML", n.d., | |||
| <https://html.spec.whatwg.org/>. | <https://html.spec.whatwg.org/>. | |||
| [RFC1034] Mockapetris, P., "Domain names - concepts and facilities", | [RFC1034] Mockapetris, P., "Domain names - concepts and facilities", | |||
| STD 13, RFC 1034, DOI 10.17487/RFC1034, November 1987, | STD 13, RFC 1034, DOI 10.17487/RFC1034, November 1987, | |||
| <https://www.rfc-editor.org/info/rfc1034>. | <https://www.rfc-editor.org/info/rfc1034>. | |||
| [RFC1123] Braden, R., Ed., "Requirements for Internet Hosts - | [RFC1123] Braden, R., Ed., "Requirements for Internet Hosts - | |||
| Application and Support", STD 3, RFC 1123, | Application and Support", STD 3, RFC 1123, | |||
| DOI 10.17487/RFC1123, October 1989, | DOI 10.17487/RFC1123, October 1989, | |||
| <https://www.rfc-editor.org/info/rfc1123>. | <https://www.rfc-editor.org/info/rfc1123>. | |||
| [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | |||
| Requirement Levels", BCP 14, RFC 2119, | Requirement Levels", BCP 14, RFC 2119, | |||
| DOI 10.17487/RFC2119, March 1997, | DOI 10.17487/RFC2119, March 1997, | |||
| <https://www.rfc-editor.org/info/rfc2119>. | <https://www.rfc-editor.org/info/rfc2119>. | |||
| [RFC3490] Costello, A., "Internationalizing Domain Names in | [RFC3490] Costello, A., "Internationalizing Domain Names in | |||
| Applications (IDNA)", RFC 3490, March 2003. | Applications (IDNA)", RFC 3490, March 2003, | |||
| <https://www.rfc-editor.org/rfc/rfc3490>. See Section 6.3 | ||||
| See Section 6.3 for an explanation why the normative | for an explanation why the normative reference to an | |||
| reference to an obsoleted specification is needed. | obsoleted specification is needed. | |||
| [RFC4790] Newman, C., Duerst, M., and A. Gulbrandsen, "Internet | [RFC4790] Newman, C., Duerst, M., and A. Gulbrandsen, "Internet | |||
| Application Protocol Collation Registry", RFC 4790, | Application Protocol Collation Registry", RFC 4790, | |||
| DOI 10.17487/RFC4790, March 2007, | DOI 10.17487/RFC4790, March 2007, | |||
| <https://www.rfc-editor.org/info/rfc4790>. | <https://www.rfc-editor.org/info/rfc4790>. | |||
| [RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax | [RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax | |||
| Specifications: ABNF", STD 68, RFC 5234, | Specifications: ABNF", STD 68, RFC 5234, | |||
| DOI 10.17487/RFC5234, January 2008, | DOI 10.17487/RFC5234, January 2008, | |||
| <https://www.rfc-editor.org/info/rfc5234>. | <https://www.rfc-editor.org/info/rfc5234>. | |||
| skipping to change at page 47, line 31 ¶ | skipping to change at page 48, line 31 ¶ | |||
| [CSRF] Barth, A., Jackson, C., and J. Mitchell, "Robust Defenses | [CSRF] Barth, A., Jackson, C., and J. Mitchell, "Robust Defenses | |||
| for Cross-Site Request Forgery", | for Cross-Site Request Forgery", | |||
| DOI 10.1145/1455770.1455782, ISBN 978-1-59593-810-7, | DOI 10.1145/1455770.1455782, ISBN 978-1-59593-810-7, | |||
| ACM CCS '08: Proceedings of the 15th ACM conference on | ACM CCS '08: Proceedings of the 15th ACM conference on | |||
| Computer and communications security (pages 75-88), | Computer and communications security (pages 75-88), | |||
| October 2008, | October 2008, | |||
| <http://portal.acm.org/citation.cfm?id=1455770.1455782>. | <http://portal.acm.org/citation.cfm?id=1455770.1455782>. | |||
| [I-D.ietf-httpbis-cookie-alone] | [I-D.ietf-httpbis-cookie-alone] | |||
| West, M., "Deprecate modification of 'secure' cookies from | West, M., "Deprecate modification of 'secure' cookies from | |||
| non-secure origins", draft-ietf-httpbis-cookie-alone-01 | non-secure origins", Work in Progress, Internet-Draft, | |||
| (work in progress), September 2016. | draft-ietf-httpbis-cookie-alone-01, 5 September 2016, | |||
| <http://www.ietf.org/internet-drafts/draft-ietf-httpbis- | ||||
| cookie-alone-01.txt>. | ||||
| [I-D.ietf-httpbis-cookie-prefixes] | [I-D.ietf-httpbis-cookie-prefixes] | |||
| West, M., "Cookie Prefixes", draft-ietf-httpbis-cookie- | West, M., "Cookie Prefixes", Work in Progress, Internet- | |||
| prefixes-00 (work in progress), February 2016. | Draft, draft-ietf-httpbis-cookie-prefixes-00, 23 February | |||
| 2016, <http://www.ietf.org/internet-drafts/draft-ietf- | ||||
| httpbis-cookie-prefixes-00.txt>. | ||||
| [I-D.ietf-httpbis-cookie-same-site] | [I-D.ietf-httpbis-cookie-same-site] | |||
| West, M. and M. Goodwin, "Same-Site Cookies", draft-ietf- | West, M. and M. Goodwin, "Same-Site Cookies", Work in | |||
| httpbis-cookie-same-site-00 (work in progress), June 2016. | Progress, Internet-Draft, draft-ietf-httpbis-cookie-same- | |||
| site-00, 20 June 2016, <http://www.ietf.org/internet- | ||||
| drafts/draft-ietf-httpbis-cookie-same-site-00.txt>. | ||||
| [prerendering] | [prerendering] | |||
| Bentzel, C., "Chrome Prerendering", n.d., | Bentzel, C., "Chrome Prerendering", n.d., | |||
| <https://www.chromium.org/developers/design-documents/ | <https://www.chromium.org/developers/design-documents/ | |||
| prerender>. | prerender>. | |||
| [PSL] "Public Suffix List", n.d., | [PSL] "Public Suffix List", n.d., | |||
| <https://publicsuffix.org/list/>. | <https://publicsuffix.org/list/>. | |||
| [RFC2818] Rescorla, E., "HTTP Over TLS", RFC 2818, | [RFC2818] Rescorla, E., "HTTP Over TLS", RFC 2818, | |||
| skipping to change at page 48, line 40 ¶ | skipping to change at page 49, line 47 ¶ | |||
| <https://www.rfc-editor.org/info/rfc6265>. | <https://www.rfc-editor.org/info/rfc6265>. | |||
| [RFC7034] Ross, D. and T. Gondrom, "HTTP Header Field X-Frame- | [RFC7034] Ross, D. and T. Gondrom, "HTTP Header Field X-Frame- | |||
| Options", RFC 7034, DOI 10.17487/RFC7034, October 2013, | Options", RFC 7034, DOI 10.17487/RFC7034, October 2013, | |||
| <https://www.rfc-editor.org/info/rfc7034>. | <https://www.rfc-editor.org/info/rfc7034>. | |||
| [UTS46] Davis, M. and M. Suignard, "Unicode IDNA Compatibility | [UTS46] Davis, M. and M. Suignard, "Unicode IDNA Compatibility | |||
| Processing", UNICODE Unicode Technical Standards # 46, | Processing", UNICODE Unicode Technical Standards # 46, | |||
| June 2016, <http://unicode.org/reports/tr46/>. | June 2016, <http://unicode.org/reports/tr46/>. | |||
| 10.3. URIs | ||||
| [1] https://lists.w3.org/Archives/Public/ietf-http-wg/ | ||||
| [2] http://httpwg.github.io/ | ||||
| [3] https://github.com/httpwg/http-extensions/labels/6265bis | ||||
| [4] https://www.iana.org/assignments/cookie-attribute-names | ||||
| [5] https://github.com/httpwg/http-extensions/issues/243 | ||||
| [6] https://github.com/httpwg/http-extensions/issues/246 | ||||
| [7] https://www.rfc-editor.org/errata_search.php?rfc=6265 | ||||
| [8] https://github.com/httpwg/http-extensions/issues/247 | ||||
| [9] https://github.com/httpwg/http-extensions/issues/201 | ||||
| [10] https://github.com/httpwg/http-extensions/issues/204 | ||||
| [11] https://github.com/httpwg/http-extensions/issues/222 | ||||
| [12] https://github.com/httpwg/http-extensions/issues/248 | ||||
| [13] https://github.com/httpwg/http-extensions/issues/295 | ||||
| [14] https://github.com/httpwg/http-extensions/issues/302 | ||||
| [15] https://github.com/httpwg/http-extensions/issues/389 | ||||
| [16] https://github.com/httpwg/http-extensions/issues/199 | ||||
| [17] https://github.com/httpwg/http-extensions/issues/788 | ||||
| [18] https://github.com/httpwg/http-extensions/issues/594 | ||||
| [19] https://github.com/httpwg/http-extensions/issues/159 | ||||
| [20] https://github.com/httpwg/http-extensions/issues/159 | ||||
| [21] https://github.com/httpwg/http-extensions/issues/901 | ||||
| [22] https://github.com/httpwg/http-extensions/pull/1035 | ||||
| [23] https://github.com/httpwg/http-extensions/pull/1038 | ||||
| [24] https://github.com/httpwg/http-extensions/pull/1040 | ||||
| [25] https://github.com/httpwg/http-extensions/pull/1047 | ||||
| [26] https://github.com/httpwg/http-extensions/issues/1059 | ||||
| [27] https://github.com/httpwg/http-extensions/issues/1158 | ||||
| [28] https://github.com/httpwg/http-extensions/pull/1060 | ||||
| [29] https://github.com/httpwg/http-extensions/issues/1074 | ||||
| [30] https://github.com/httpwg/http-extensions/issues/1119 | ||||
| [31] https://github.com/httpwg/http-extensions/pull/1143 | ||||
| [32] https://github.com/httpwg/http-extensions/issues/1159 | ||||
| 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. | * 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 | * Fixes to formatting caused by mistakes in the initial port to | |||
| Markdown: | Markdown: | |||
| * https://github.com/httpwg/http-extensions/issues/243 [5] | - https://github.com/httpwg/http-extensions/issues/243 | |||
| (https://github.com/httpwg/http-extensions/issues/243) | ||||
| * https://github.com/httpwg/http-extensions/issues/246 [6] | - https://github.com/httpwg/http-extensions/issues/246 | |||
| (https://github.com/httpwg/http-extensions/issues/246) | ||||
| o Addresses errata 3444 by updating the "path-value" and "extension- | * Addresses errata 3444 by updating the "path-value" and "extension- | |||
| av" grammar, errata 4148 by updating the "day-of-month", "year", | av" grammar, errata 4148 by updating the "day-of-month", "year", | |||
| and "time" grammar, and errata 3663 by adding the requested note. | and "time" grammar, and errata 3663 by adding the requested note. | |||
| https://www.rfc-editor.org/errata_search.php?rfc=6265 [7] | https://www.rfc-editor.org/errata_search.php?rfc=6265 | |||
| (https://www.rfc-editor.org/errata_search.php?rfc=6265) | ||||
| o Dropped "Cookie2" and "Set-Cookie2" from the IANA Considerations | * Dropped "Cookie2" and "Set-Cookie2" from the IANA Considerations | |||
| section: https://github.com/httpwg/http-extensions/issues/247 [8] | section: https://github.com/httpwg/http-extensions/issues/247 | |||
| (https://github.com/httpwg/http-extensions/issues/247) | ||||
| o Merged the recommendations from [I-D.ietf-httpbis-cookie-alone], | * Merged the recommendations from [I-D.ietf-httpbis-cookie-alone], | |||
| removing the ability for a non-secure origin to set cookies with a | removing the ability for a non-secure origin to set cookies with a | |||
| 'secure' flag, and to overwrite cookies whose 'secure' flag is | 'secure' flag, and to overwrite cookies whose 'secure' flag is | |||
| true. | true. | |||
| o Merged the recommendations from | * Merged the recommendations from | |||
| [I-D.ietf-httpbis-cookie-prefixes], adding "__Secure-" and | [I-D.ietf-httpbis-cookie-prefixes], adding "__Secure-" and | |||
| "__Host-" cookie name prefix processing instructions. | "__Host-" cookie name prefix processing instructions. | |||
| A.3. draft-ietf-httpbis-rfc6265bis-02 | A.3. draft-ietf-httpbis-rfc6265bis-02 | |||
| o Merged the recommendations from | * Merged the recommendations from | |||
| [I-D.ietf-httpbis-cookie-same-site], adding support for the | [I-D.ietf-httpbis-cookie-same-site], adding support for the | |||
| "SameSite" attribute. | "SameSite" attribute. | |||
| o Closed a number of editorial bugs: | * Closed a number of editorial bugs: | |||
| * Clarified address bar behavior for SameSite cookies: | - Clarified address bar behavior for SameSite cookies: | |||
| https://github.com/httpwg/http-extensions/issues/201 [9] | https://github.com/httpwg/http-extensions/issues/201 | |||
| (https://github.com/httpwg/http-extensions/issues/201) | ||||
| * Added the word "Cookies" to the document's name: | - Added the word "Cookies" to the document's name: | |||
| https://github.com/httpwg/http-extensions/issues/204 [10] | https://github.com/httpwg/http-extensions/issues/204 | |||
| (https://github.com/httpwg/http-extensions/issues/204) | ||||
| * Clarified that the "__Host-" prefix requires an explicit "Path" | - Clarified that the "__Host-" prefix requires an explicit "Path" | |||
| attribute: https://github.com/httpwg/http-extensions/issues/222 | attribute: https://github.com/httpwg/http-extensions/issues/222 | |||
| [11] | (https://github.com/httpwg/http-extensions/issues/222) | |||
| * Expanded the options for dealing with third-party cookies to | - Expanded the options for dealing with third-party cookies to | |||
| include a brief mention of partitioning based on first-party: | include a brief mention of partitioning based on first-party: | |||
| https://github.com/httpwg/http-extensions/issues/248 [12] | https://github.com/httpwg/http-extensions/issues/248 | |||
| (https://github.com/httpwg/http-extensions/issues/248) | ||||
| * Noted that double-quotes in cookie values are part of the | - Noted that double-quotes in cookie values are part of the | |||
| value, and are not stripped: https://github.com/httpwg/http- | value, and are not stripped: https://github.com/httpwg/http- | |||
| extensions/issues/295 [13] | extensions/issues/295 (https://github.com/httpwg/http- | |||
| extensions/issues/295) | ||||
| * Fixed the "site for cookies" algorithm to return something that | - Fixed the "site for cookies" algorithm to return something that | |||
| makes sense: https://github.com/httpwg/http-extensions/ | makes sense: https://github.com/httpwg/http-extensions/ | |||
| issues/302 [14] | issues/302 (https://github.com/httpwg/http-extensions/ | |||
| issues/302) | ||||
| A.4. draft-ietf-httpbis-rfc6265bis-03 | A.4. draft-ietf-httpbis-rfc6265bis-03 | |||
| o Clarified handling of invalid SameSite values: | * Clarified handling of invalid SameSite values: | |||
| https://github.com/httpwg/http-extensions/issues/389 [15] | https://github.com/httpwg/http-extensions/issues/389 | |||
| (https://github.com/httpwg/http-extensions/issues/389) | ||||
| o Reflect widespread implementation practice of including a cookie's | * Reflect widespread implementation practice of including a cookie's | |||
| "host-only-flag" when calculating its uniqueness: | "host-only-flag" when calculating its uniqueness: | |||
| https://github.com/httpwg/http-extensions/issues/199 [16] | https://github.com/httpwg/http-extensions/issues/199 | |||
| (https://github.com/httpwg/http-extensions/issues/199) | ||||
| o Introduced an explicit "None" value for the SameSite attribute: | * Introduced an explicit "None" value for the SameSite attribute: | |||
| https://github.com/httpwg/http-extensions/issues/788 [17] | https://github.com/httpwg/http-extensions/issues/788 | |||
| (https://github.com/httpwg/http-extensions/issues/788) | ||||
| A.5. draft-ietf-httpbis-rfc6265bis-04 | A.5. draft-ietf-httpbis-rfc6265bis-04 | |||
| o Allow "SameSite" cookies to be set for all top-level navigations. | * Allow "SameSite" cookies to be set for all top-level navigations. | |||
| https://github.com/httpwg/http-extensions/issues/594 [18] | https://github.com/httpwg/http-extensions/issues/594 | |||
| (https://github.com/httpwg/http-extensions/issues/594) | ||||
| o Treat "Set-Cookie: token" as creating the cookie "("", "token")": | * Treat "Set-Cookie: token" as creating the cookie "("", "token")": | |||
| https://github.com/httpwg/http-extensions/issues/159 [19] | https://github.com/httpwg/http-extensions/issues/159 | |||
| (https://github.com/httpwg/http-extensions/issues/159) | ||||
| o Reject cookies with neither name nor value (e.g. "Set-Cookie: =" | * Reject cookies with neither name nor value (e.g. "Set-Cookie: =" | |||
| and "Set-Cookie:": https://github.com/httpwg/http-extensions/ | and "Set-Cookie:": https://github.com/httpwg/http-extensions/ | |||
| issues/159 [20] | issues/159 (https://github.com/httpwg/http-extensions/issues/159) | |||
| o Clarified behavior of multiple "SameSite" attributes in a cookie | * Clarified behavior of multiple "SameSite" attributes in a cookie | |||
| string: https://github.com/httpwg/http-extensions/issues/901 [21] | string: https://github.com/httpwg/http-extensions/issues/901 | |||
| (https://github.com/httpwg/http-extensions/issues/901) | ||||
| A.6. draft-ietf-httpbis-rfc6265bis-05 | A.6. draft-ietf-httpbis-rfc6265bis-05 | |||
| o Typos and editorial fixes: https://github.com/httpwg/http- | * Typos and editorial fixes: https://github.com/httpwg/http- | |||
| extensions/pull/1035 [22], https://github.com/httpwg/http- | extensions/pull/1035 (https://github.com/httpwg/http-extensions/ | |||
| extensions/pull/1038 [23], https://github.com/httpwg/http- | pull/1035), https://github.com/httpwg/http-extensions/pull/1038 | |||
| extensions/pull/1040 [24], https://github.com/httpwg/http- | (https://github.com/httpwg/http-extensions/pull/1038), | |||
| extensions/pull/1047 [25]. | https://github.com/httpwg/http-extensions/pull/1040 | |||
| (https://github.com/httpwg/http-extensions/pull/1040), | ||||
| https://github.com/httpwg/http-extensions/pull/1047 | ||||
| (https://github.com/httpwg/http-extensions/pull/1047). | ||||
| A.7. draft-ietf-httpbis-rfc6265bis-06 | A.7. draft-ietf-httpbis-rfc6265bis-06 | |||
| o Editorial fixes: https://github.com/httpwg/http-extensions/ | * Editorial fixes: https://github.com/httpwg/http-extensions/ | |||
| issues/1059 [26], https://github.com/httpwg/http-extensions/ | issues/1059 (https://github.com/httpwg/http-extensions/ | |||
| issues/1158 [27]. | issues/1059), https://github.com/httpwg/http-extensions/ | |||
| issues/1158 (https://github.com/httpwg/http-extensions/ | ||||
| issues/1158). | ||||
| o Created a registry for cookie attribute names: | * Created a registry for cookie attribute names: | |||
| https://github.com/httpwg/http-extensions/pull/1060 [28]. | https://github.com/httpwg/http-extensions/pull/1060 | |||
| (https://github.com/httpwg/http-extensions/pull/1060). | ||||
| o Tweaks to ABNF for "cookie-pair" and the "Cookie" header | * Tweaks to ABNF for "cookie-pair" and the "Cookie" header | |||
| production: https://github.com/httpwg/http-extensions/issues/1074 | production: https://github.com/httpwg/http-extensions/issues/1074 | |||
| [29], https://github.com/httpwg/http-extensions/issues/1119 [30]. | (https://github.com/httpwg/http-extensions/issues/1074), | |||
| https://github.com/httpwg/http-extensions/issues/1119 | ||||
| (https://github.com/httpwg/http-extensions/issues/1119). | ||||
| o Fixed serialization for nameless/valueless cookies: | * Fixed serialization for nameless/valueless cookies: | |||
| https://github.com/httpwg/http-extensions/pull/1143 [31]. | https://github.com/httpwg/http-extensions/pull/1143 | |||
| (https://github.com/httpwg/http-extensions/pull/1143). | ||||
| o Converted a normative reference to Mozilla's Public Suffix List | * Converted a normative reference to Mozilla's Public Suffix List | |||
| [PSL] into an informative reference: https://github.com/httpwg/ | [PSL] into an informative reference: https://github.com/httpwg/ | |||
| http-extensions/issues/1159 [32]. | http-extensions/issues/1159 (https://github.com/httpwg/http- | |||
| extensions/issues/1159). | ||||
| A.8. draft-ietf-httpbis-rfc6265bis-07 | ||||
| * Moved instruction to ignore cookies with empty cookie-name and | ||||
| cookie-value from Section 5.3 to Section 5.4 to ensure that they | ||||
| apply to cookies created without parsing a cookie string: | ||||
| https://github.com/httpwg/http-extensions/issues/1234 | ||||
| (https://github.com/httpwg/http-extensions/issues/1234). | ||||
| * Add a default enforcement value to the "same-site-flag", | ||||
| equivalent to "SameSite=Lax": https://github.com/httpwg/http- | ||||
| extensions/pull/1325 (https://github.com/httpwg/http-extensions/ | ||||
| pull/1325). | ||||
| * Require a Secure attribute for "SameSite=None": | ||||
| https://github.com/httpwg/http-extensions/pull/1323 | ||||
| (https://github.com/httpwg/http-extensions/pull/1323). | ||||
| * Consider scheme when running the same-site algorithm: | ||||
| https://github.com/httpwg/http-extensions/pull/1324 | ||||
| (https://github.com/httpwg/http-extensions/pull/1324). | ||||
| 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 a minor update | |||
| of RFC 6265, adding small features, and aligning the specification | of RFC 6265, adding small features, and aligning the specification | |||
| with the reality of today's deployments. Here, we're standing upon | with the reality of today's deployments. Here, we're standing upon | |||
| the shoulders of a giant since the majority of the text is still | the shoulders of a giant since the majority of the text is still | |||
| Adam's. | Adam's. | |||
| Authors' Addresses | Authors' Addresses | |||
| End of changes. 132 change blocks. | ||||
| 324 lines changed or deleted | 331 lines changed or added | |||
This html diff was produced by rfcdiff 1.45. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ | ||||