Skip to content

Commit 8ec8d64

Browse files
bvandersloot-mozillajohannhofannevk
authored andcommitted
Integrate with HTTP WG's layered-cookies work
This builds on whatwg/html#10991 and whatwg/html#11133. This should be a mostly editorial change, but with much more clarity about how the state flows into the IETF side. Co-authored-by: Johann Hofmann <[email protected]> Co-authored-by: Anne van Kesteren <[email protected]>
1 parent 6d4f683 commit 8ec8d64

File tree

1 file changed

+172
-42
lines changed

1 file changed

+172
-42
lines changed

fetch.bs

Lines changed: 172 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -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,
92179346
Ben Kelly,
92189347
Benjamin Gruenbaum,
92199348
Benjamin Hawkes-Lewis,
9349+
Benjamin VanderSloot,
92209350
Bert Bos,
92219351
Björn Höhrmann,
92229352
Boris Zbarsky,

0 commit comments

Comments
 (0)