@@ -55,10 +55,24 @@ urlPrefix:https://tc39.es/ecma262/#;type:dfn;spec:ecma-262
5555 url:realm;text:realm
5656 url:sec-list-and-record-specification-type;text:Record
5757 url:current-realm;text:current realm
58+
59+ urlPrefix:https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-layered-cookies#;type:dfn;spec:cookies
60+ url:name-cookie-store-and-limits;text:cookie store
61+ url:name-parse-and-store-a-cookie;text:parse and store a cookie
62+ url:name-parse-a-cookie;text:parse a cookie
63+ url:name-store-a-cookie;text:store a cookie
64+ url:name-retrieve-cookies;text:retrieve cookies
65+ url:name-serialize-cookies;text:serialize cookies
66+ url:name-garbage-collect-cookies;text:garbage collect cookies
5867</pre>
5968
6069<pre class=biblio>
6170{
71+ "COOKIES": {
72+ "authors": ["Johann Hofmann", "Anne van Kesteren"] ,
73+ "href": "https://httpwg.org/http-extensions/draft-ietf-httpbis-layered-cookies.html",
74+ "title": "Cookies: HTTP State Management Mechanism"
75+ },
6276 "HTTP": {
6377 "aliasOf": "RFC9110"
6478 },
@@ -1973,6 +1987,10 @@ not always relevant and might require different behavior.
19731987<a lt=fetch for=/>fetching</a> . It provides a convenient way for standards to not have to set
19741988<a for=/>request</a> 's <a for=request>origin</a> .
19751989
1990+ <p> A <a for=/>request</a> has an associated
1991+ <dfn export for=request>top-level navigation initiator origin</dfn> , which is an <a for=/>origin</a>
1992+ or null. Unless stated otherwise it is null.
1993+
19761994<p> A <a for=/>request</a> has an associated
19771995<dfn export for=request id=concept-request-policy-container>policy container</dfn> , which is
19781996"<code> client</code> " or a <a for=/>policy container</a> . Unless stated otherwise it is
@@ -2257,31 +2275,39 @@ or "<code>object</code>".
22572275<hr>
22582276
22592277<div algorithm>
2260- <p> A <a for=/> request</a> <var> request</var> has a
2261- <dfn for=request id=concept-request-tainted-origin>redirect-tainted origin</dfn> if these steps
2262- return true:
2278+ <p> To compute the <dfn for=request id=concept- request-tainted-origin>redirect-taint</dfn> of a
2279+ <a for=/> request</a> <var> request </var> , perform the following steps. They return
2280+ " <code> same-origin </code> ", " <code> same-site </code> ", or " <code> cross-site </code> ".
22632281
22642282<ol>
22652283 <li><p> <a for=/>Assert</a> : <var> request</var> 's <a for=request>origin</a> is not
22662284 "<code> client</code> ".
22672285
22682286 <li><p> Let <var> lastURL</var> be null.
22692287
2288+ <li><p> Let <var> taint</var> be "<code> same-origin</code> ".
2289+
22702290 <li>
22712291 <p> <a for=list>For each</a> <var> url</var> of <var> request</var> 's <a for=request>URL list</a> :
22722292
22732293 <ol>
22742294 <li><p> If <var> lastURL</var> is null, then set <var> lastURL</var> to <var> url</var> and
22752295 <a for=iteration>continue</a> .
22762296
2297+ <li><p> If <var> url</var> 's <a for=url>origin</a> is not <a for=/>same site</a> with
2298+ <var> lastURL</var> 's <a for=url>origin</a> and <var>request</var>' s <a for=request>origin</a> is
2299+ not <a for=/>same site</a> with <var> lastURL</var> 's <a for=url>origin</a> , then return
2300+ "<code> cross-site</code> ".
2301+
22772302 <li><p> If <var> url</var> 's <a for=url>origin</a> is not <a>same origin</a> with
22782303 <var> lastURL</var> 's <a for=url>origin</a> and <var>request</var>' s <a for=request>origin</a> is
2279- not <a>same origin</a> with <var> lastURL</var> 's <a for=url>origin</a> , then return true.
2304+ not <a>same origin</a> with <var> lastURL</var> 's <a for=url>origin</a> , then set
2305+ <var> taint</var> to "<code> same-site</code> ".
22802306
2281- <li> Set <var> lastURL</var> to <var> url</var> .
2307+ <li><p> Set <var> lastURL</var> to <var> url</var> .
22822308 </ol>
22832309
2284- <li> Return false .
2310+ <li><p> Return <var> taint </var> .
22852311</ol>
22862312</div>
22872313
@@ -2293,8 +2319,8 @@ run these steps:
22932319 <li><p> <a for=/>Assert</a> : <var> request</var> 's <a for=request>origin</a> is not
22942320 "<code> client</code> ".
22952321
2296- <li><p> If <var> request</var> has a <a for=request>redirect-tainted origin </a> , then return
2297- "<code> null</code> ".
2322+ <li><p> If <var> request</var> 's <a for=request>redirect-taint </a> is not " <code> same-origin </code> ",
2323+ then return "<code> null</code> ".
22982324
22992325 <li><p> Return <var> request</var> 's <a for=request>origin</a> ,
23002326 <a lt="ASCII serialization of an origin">serialized</a> .
@@ -2393,20 +2419,20 @@ source of security bugs. Please seek security review for features that deal with
23932419 "<code> client</code> ".
23942420
23952421 <li><p> If <var> request</var> 's <a for=request>mode</a> is not "<code> no-cors</code> ", then return
2396- true.</p>
2422+ true.
23972423
2398- <li><p> If <var> request</var> 's <a for=request>client</a> is null, then return true.</p>
2424+ <li><p> If <var> request</var> 's <a for=request>client</a> is null, then return true.
23992425
24002426 <li><p> If <var> request</var> 's <a for=request>client</a>' s
24012427 <a for="environment settings object">policy container</a> 's
24022428 <a for="policy container">embedder policy</a> 's <a for="embedder policy">value</a> is not
2403- "<a for="embedder policy value"><code>credentialless</code></a> ", then return true.</p>
2429+ "<a for="embedder policy value"><code>credentialless</code></a> ", then return true.
24042430
24052431 <li><p> If <var> request</var> 's <a for=request>origin</a> is <a>same origin</a> with
2406- <var> request</var> 's <a for=request>current URL</a>' s <a for=url>origin</a> and <var> request</var>
2407- does not have a <a for=request>redirect-tainted origin</a> , then return true.</p>
2432+ <var> request</var> 's <a for=request>current URL</a>' s <a for=url>origin</a> and <var> request</var> 's
2433+ <a for=request>redirect-taint</a> is not " <code> same- origin</code> " , then return true.
24082434
2409- <li><p> Return false.</p>
2435+ <li><p> Return false.
24102436</ol>
24112437</div>
24122438
@@ -2517,8 +2543,9 @@ this is also tracked internally using the request's <a for=request>timing allow
25172543<dfn export for=response>service worker timing info</dfn> (null or a
25182544<a for=/>service worker timing info</a> ), which is initially null.
25192545
2520- <p> A <a for=/>response</a> has an associated <dfn for=response>has-cross-origin-redirects</dfn>
2521- (a boolean), which is initially false.
2546+ <p> A <a for=/>response</a> has an associated <dfn for=response>redirect taint</dfn>
2547+ ("<code> same-origin</code> ", "<code> same-site</code> ", or "<code> cross-site</code> "), which is
2548+ initially "<code> same-origin</code> ".
25222549
25232550<hr>
25242551
@@ -3323,6 +3350,127 @@ through TLS using ALPN. The protocol cannot be spoofed through HTTP requests in
33233350
33243351<h2 id=http-extensions>HTTP extensions</h2>
33253352
3353+ <h3 id=cookies>Cookies</h3>
3354+
3355+ <p> The `<code> Cookie</code> ` request header and `<code> Set-Cookie</code> ` response headers are
3356+ largely defined in their own specifications. We define additional infrastructure to be able to use
3357+ them conveniently here. [[COOKIES]] .
3358+
3359+
3360+ <h4 id=cookie-header>`<code>Cookie</code>` header</h4>
3361+
3362+ <div algorithm>
3363+ <p> To <dfn>append a request `<code>Cookie</code>` header</dfn> , given a <a for=/>request</a>
3364+ <var> request</var> :
3365+
3366+ <ol>
3367+ <li><p> If the user agent is configured to disable cookies for <var> request</var> , then it should
3368+ return.
3369+
3370+ <li><p> Let |sameSite| be the result of [=determining the same-site mode=] for <var> request</var> .
3371+
3372+ <li><p> Let |isSecure| be true if <var> request</var> 's <a for=request>current URL</a>' s
3373+ <a for=url>scheme</a> is "<code> https</code> "; otherwise false.
3374+
3375+ <li>
3376+ <p> Let |httpOnlyAllowed| be true.
3377+
3378+ <p class=note> True follows from this being invoked from <a>fetch</a> , as opposed to the
3379+ <code> document.cookie</code> getter steps for instance.
3380+
3381+ <li>
3382+ <p> Let |cookies| be the result of running <a>retrieve cookies</a> given |isSecure|,
3383+ <var> request</var> 's <a for=request>current URL</a>' s <a for=url>host</a> , <var> request</var> 's
3384+ <a for=request>current URL</a> 's <a for=url>path</a> , |httpOnlyAllowed|, and |sameSite|.
3385+
3386+ <p class=note> The cookie store returns an ordered list of cookies
3387+
3388+ <li><p> If |cookies| <a for="list">is empty</a> , then return.
3389+
3390+ <li><p> Let |value| be the result of running <a>serialize cookies</a> given |cookies|.
3391+
3392+ <li><p> <a for="header list">Append</a> (`<code> Cookie</code> `, <var> value</var> ) to
3393+ <var> request</var> 's <a for=request>header list</a> .
3394+ </ol>
3395+ </div>
3396+
3397+
3398+ <h4 id=set-cookie-header>`<code>Set-Cookie</code>` header</h4>
3399+
3400+ <div algorithm>
3401+ <p> To <dfn>parse and store response `<code>Set-Cookie</code>` headers</dfn> , given a
3402+ <a for=/>request</a> <var> request</var> and a <a for=/>response</a> <var> response</var> :
3403+
3404+ <ol>
3405+ <li><p> If the user agent is configured to disable cookies for <var> request</var> , then it should
3406+ return.
3407+
3408+ <li><p> Let |allowNonHostOnlyCookieForPublicSuffix| be false.
3409+
3410+ <li><p> Let |isSecure| be true if <var> request</var> 's <a for=request>current URL</a>' s
3411+ <a for=url>scheme</a> is "<code> https</code> "; otherwise false.
3412+
3413+ <li>
3414+ <p> Let |httpOnlyAllowed| be true.
3415+
3416+ <p class=note> True follows from this being invoked from <a>fetch</a> , as opposed to the
3417+ <code> document.cookie</code> getter steps for instance.
3418+
3419+ <li><p> Let |sameSiteStrictOrLaxAllowed| be true if the result of [=determine the same-site mode=]
3420+ for |request| is "<code> strict-or-less</code> "; otherwise false.
3421+
3422+ <li>
3423+ <p> <a for=list>For each</a> <var> header</var> of <var> response</var> 's
3424+ <a for=response>header list</a> :
3425+
3426+ <ol>
3427+ <li><p> If <var> header</var> 's <a for=header>name</a> is not a <a>byte-case-insensitive</a> match
3428+ for `<code> Set-Cookie</code> `, then <a for=iteration>continue</a> .
3429+
3430+ <li><p> <a>Parse and store a cookie</a> given <var> header</var> 's <a for=header>value</a> ,
3431+ |isSecure|, <var> request</var> 's <a for=request>current URL</a>' s <a for=url>host</a> ,
3432+ <var> request</var> 's <a for=request>current URL</a>' s <a for=url>path</a> , |httpOnlyAllowed|,
3433+ |allowNonHostOnlyCookieForPublicSuffix|, and |sameSiteStrictOrLaxAllowed|.
3434+
3435+ <li><p> <a>Garbage collect cookies</a> given <var> request</var> 's <a for=request>current URL</a>' s
3436+ <a for=url>host</a> .
3437+ </ol>
3438+
3439+ <p class=note> As noted elsewhere the `<code> Set-Cookie</code> ` header cannot be combined and
3440+ therefore each occurrence is processed independently. This is not allowed for any other header.
3441+ </ol>
3442+ </div>
3443+
3444+
3445+ <h4 id=cookie-infrastructure>Cookie infrastructure</h4>
3446+
3447+ <div algorithm>
3448+ <p> To <dfn>determine the same-site mode</dfn> for a given <a for=/>request</a> <var> request</var> :
3449+
3450+ <ol>
3451+ <li><p> <a for=/>Assert</a> : <var> request</var> 's <a for=request>method</a> is "<code> GET</code> "
3452+ or "<code> POST</code> ".
3453+
3454+ <li><p> If <var> request</var> 's <a for=request>top-level navigation initiator origin</a> is not
3455+ null and is not <a for=/>same site</a> with <var> request</var> 's <a for=request>URL</a>' s
3456+ <a for=url>origin</a> , then return "<code> unset-or-less</code> ".
3457+
3458+ <li><p> If <var> request</var> 's <a for=request>method</a> is "<code> GET</code> " and
3459+ <var> request</var> 's <a for=request>destination</a> is "document", then return
3460+ "<code> lax-or-less</code> ".
3461+
3462+ <li><p> If <var> request</var> 's <a for=request>client</a>' s
3463+ <a for="environment settings object">has cross-site ancestor</a> is true, then return
3464+ "<code> unset-or-less</code> ".
3465+
3466+ <li><p> If <var> request</var> 's <a for=request>redirect-taint</a> is "<code> cross-site</code> ", then
3467+ return "<code> unset-or-less</code> ".
3468+
3469+ <li><p> Return "<code> strict-or-less</code> ".
3470+ </ol>
3471+ </div>
3472+
3473+
33263474<h3 id=origin-header>`<code>Origin</code>` header</h3>
33273475
33283476<p> The `<dfn export http-header id=http-origin><code>Origin</code></dfn> `
@@ -4737,8 +4885,8 @@ steps:
47374885 <!-- If you are ever tempted to move this around, carefully consider responses from about URLs,
47384886 blob URLs, service workers, HTTP cache, HTTP network, etc. -->
47394887
4740- <li><p> If <var> request </var> has a <a for=request >redirect-tainted origin </a> , then set
4741- <var> internalResponse </var> 's < a for=response>has-cross-origin-redirects </a> to true .
4888+ <li><p> Set <var> internalResponse </var> 's <a for=response >redirect taint </a> to <var>request</var>' s
4889+ <a for=request>redirect-taint </a> .
47424890
47434891 <li><p> If <var> request</var> 's <a for=request>timing allow failed flag</a> is unset, then set
47444892 <var> internalResponse</var> 's <a for=response>timing allow passed flag</a> .
@@ -4891,7 +5039,7 @@ steps:
48915039 <li>
48925040 <p> If <var> fetchParams</var> 's <a for="fetch params">request</a>' s <a for=request>mode</a> is
48935041 not "<code> navigate</code> " or <var> response</var> 's
4894- <a for=response>has-cross-origin-redirects </a> is false :
5042+ <a for=response>redirect taint </a> is " <code> same-origin </code> " :
48955043
48965044 <ol>
48975045 <li><p> Set <var> responseStatus</var> to <var> response</var> 's <a for=response>status</a> .
@@ -5774,21 +5922,7 @@ run these steps:
57745922 <p> If <var> includeCredentials</var> is true, then:
57755923
57765924 <ol>
5777- <li>
5778- <p> If the user agent is not configured to block cookies for <var> httpRequest</var> (see
5779- <a href=https://httpwg.org/specs/rfc6265.html#privacy-considerations>section 7</a> of
5780- [[!COOKIES]] ), then:
5781-
5782- <ol>
5783- <li><p> Let <var> cookies</var> be the result of running the "cookie-string" algorithm (see
5784- <a href=https://httpwg.org/specs/rfc6265.html#cookie>section 5.4</a> of
5785- [[!COOKIES]] ) with the user agent's cookie store and <var> httpRequest</var> 's
5786- <a for=request>current URL</a> .
5787-
5788- <li> If <var> cookies</var> is not the empty string, then <a for="header list">append</a>
5789- (`<code> Cookie</code> `, <var> cookies</var> ) to <var> httpRequest</var> 's
5790- <a for=request>header list</a> .
5791- </ol>
5925+ <li><p> <a>Append a request `<code>Cookie</code>` header</a> for <var> httpRequest</var> .
57925926
57935927 <li>
57945928 <p> If <var> httpRequest</var> 's <a for=request>header list</a>
@@ -6404,14 +6538,9 @@ optional boolean <var>forceNewConnection</var> (default false), run these steps:
64046538 <li><p> Set <var> response</var> 's <a for=response>body</a> to a new <a for=/>body</a> whose
64056539 <a for=body>stream</a> is <var> stream</var> .
64066540
6407- <li><p tracking-vector> If <var> includeCredentials</var> is true and the user agent is not
6408- configured to block cookies for <var> request</var> (see
6409- <a href=https://httpwg.org/specs/rfc6265.html#privacy-considerations>section 7</a> of
6410- [[!COOKIES]] ), then run the "set-cookie-string" parsing algorithm (see
6411- <a href=https://httpwg.org/specs/rfc6265.html#set-cookie>section 5.2</a> of [[!COOKIES]] ) on the
6412- <a for=header>value</a> of each <a for=/>header</a> whose <a for=header>name</a> is a
6413- <a>byte-case-insensitive</a> match for `<code> Set-Cookie</code> ` in <var> response</var> 's
6414- <a for=response>header list</a> , if any, and <var> request</var> 's <a for=request>current URL</a> .
6541+ <li><p tracking-vector> If <var> includeCredentials</var> is true, then the user agent should
6542+ <a>parse and store response `<code>Set-Cookie</code>` headers</a> given <var> request</var> and
6543+ <var> response</var> .
64156544
64166545 <li>
64176546 <p> Run these steps <a>in parallel</a> :
@@ -9217,6 +9346,7 @@ Axel Rauschmayer,
92179346Ben Kelly,
92189347Benjamin Gruenbaum,
92199348Benjamin Hawkes-Lewis,
9349+ Benjamin VanderSloot,
92209350Bert Bos,
92219351Björn Höhrmann,
92229352Boris Zbarsky,
0 commit comments