Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Cookie Layering] WIP Requests #1707

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
133 changes: 107 additions & 26 deletions fetch.bs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ urlPrefix:https://httpwg.org/specs/rfc9111.html#;type:dfn;spec:http-caching
urlPrefix:https://httpwg.org/specs/rfc9112.html#;type:dfn;spec:http1
url:status.line;text:reason-phrase

urlPrefix:https://https://html-preview.github.io/?url=https://raw.githubusercontent.com/johannhof/http-extensions/gh-pages/draft-ietf-httpbis-rfc6265bis.html#;type:dfn;spec:cookies
url:name-serialize-cookies;text:serialize cookies
url:name-retrieve-cookies;text:retrieve cookies

url:https://w3c.github.io/resource-timing/#dfn-mark-resource-timing;text:mark resource timing;type:dfn;spec:resource-timing

urlPrefix:https://w3c.github.io/hr-time/#;spec:hr-time
Expand All @@ -53,10 +57,20 @@ urlPrefix:https://tc39.es/ecma262/#;type:dfn;spec:ecma-262
url:realm;text:realm
url:sec-list-and-record-specification-type;text:Record
url:current-realm;text:current realm

spec: storage-access; urlPrefix: https://privacycg.github.io/storage-access
type: dfn
for: environment
text: has storage access; url: #environment-has-storage-access
</pre>

<pre class=biblio>
{
"COOKIES": {
"authors": ["Johann Hofmann", "Anne Van Kesteren"],
"href": "https://html-preview.github.io/?url=https://raw.githubusercontent.com/johannhof/http-extensions/gh-pages/draft-ietf-httpbis-rfc6265bis.html#name-retrieve-cookies",
"title": "Cookies: HTTP State Management Mechanism"
},
"HTTP": {
"aliasOf": "RFC9110"
},
Expand Down Expand Up @@ -2222,9 +2236,8 @@ or "<code>object</code>".
<hr>

<div algorithm>
<p>A <a for=/>request</a> <var>request</var> has a
<dfn for=request id=concept-request-tainted-origin>redirect-tainted origin</dfn> if these steps
return true:
<p>To get <a for=/>request</a> <var>request</var>'s
<dfn for=request id=concept-request-redirect-taint>redirect-taint</dfn>:

<ol>
<li><p>Let <var>lastURL</var> be null.
Expand All @@ -2236,23 +2249,26 @@ return true:
<li><p>If <var>lastURL</var> is null, then set <var>lastURL</var> to <var>url</var> and
<a for=iteration>continue</a>.

<li><p>If <var>url</var>'s <a for=url>origin</a> is not <a for=/>same site</a> with
<var>lastURL</var>'s <a for=url>origin</a> and <var>request</var>'s <a for=request>origin</a> is
not <a for=/>same site</a> with <var>lastURL</var>'s <a for=url>origin</a>, then return "Cross-Site".

<li><p>If <var>url</var>'s <a for=url>origin</a> is not <a>same origin</a> with
<var>lastURL</var>'s <a for=url>origin</a> and <var>request</var>'s <a for=request>origin</a> is
not <a>same origin</a> with <var>lastURL</var>'s <a for=url>origin</a>, then return true.
not <a>same origin</a> with <var>lastURL</var>'s <a for=url>origin</a>, then return "Same-Site-Cross-Origin".

<li>Set <var>lastURL</var> to <var>url</var>.
</ol>

<li>Return false.
<li>Return "None".
</ol>
</div>

<div algorithm>
<p><dfn>Serializing a request origin</dfn>, given a <a for=/>request</a> <var>request</var>, is to
run these steps:

<ol>
<li><p>If <var>request</var> has a <a for=request>redirect-tainted origin</a>, then return
<li><p>If <var>request</var>'s <a for=request>redirect-taint</a> is not "None", then return
"<code>null</code>".

<li><p>Return <var>request</var>'s <a for=request>origin</a>,
Expand Down Expand Up @@ -2358,8 +2374,8 @@ source of security bugs. Please seek security review for features that deal with
"<a for="embedder policy value"><code>credentialless</code></a>", then return true.</p>

<li><p>If <var>request</var>'s <a for=request>origin</a> is <a>same origin</a> with
<var>request</var>'s <a for=request>current URL</a>'s <a for=url>origin</a> and <var>request</var>
does not have a <a for=request>redirect-tainted origin</a>, then return true.</p>
<var>request</var>'s <a for=request>current URL</a>'s <a for=url>origin</a> and <var>request</var>'s
<a for=request>redirect-taint</a> is not "None", then return true.</p>

<li><p>Return false.</p>
</ol>
Expand Down Expand Up @@ -2475,6 +2491,8 @@ this is also tracked internally using the request's <a for=request>timing allow
<p>A <a for=/>response</a> has an associated <dfn for=response>has-cross-origin-redirects</dfn>
(a boolean), which is initially false.

<p>A <a for=/>response</a> has an associated <dfn for=response>has-cross-site-redirects</dfn>
(a boolean), which is initially false.
<hr>

<p>A <dfn export id=concept-network-error>network error</dfn> is a <a for=/>response</a> whose
Expand Down Expand Up @@ -3275,6 +3293,81 @@ through TLS using ALPN. The protocol cannot be spoofed through HTTP requests in

<h2 id=http-extensions>HTTP extensions</h2>

<h3 id=cookie-header>`<code>Cookie</code>` header</h3>

<p>The `<dfn export http-header id=http-cookie><code>Cookie</code></dfn>`
request <a for=/>header</a> allows the request to carry locally stored state, such as user credentials.
<div algorithm>
<p>To <dfn id=append-a-request-cookie-header>append a request `<code>Cookie</code>` header</dfn>,
given a <a for=/>request</a> <var>request</var>, run these steps:
<ol>
<li><p>Let |sameSite| be the result of [=determining the same-site mode=] for <var>request</var>.
<li><p>Let |isSecure| be false.
<li><p>If <var>request</var>'s <a for=request>current URL</a>'s <a for=url>scheme</a> is "<code>https</code>", then set |isSecure| to true.
<p class=note>Note that this doesn't use the arguably superior definition of [=secure context=]
<li><p>Let |httpOnlyAllowed| be true.
<p class=note>Fetch implies that the request is http-only, as opposed to document.cookie
<li><p>Let |partitionKey| be the result of [=computing the cookie partition key=] for <var>request</var>.
<li><p>Let |partitionedContext| be the result of [=determining the partitioned context state=] for |request|.
<li><p>Let |cookies| be the result of running <a>retrieve cookies</a> given
|isSecure|,
<var>request</var>'s <a for=request>current URL</a>'s <a for=url>host</a>,
<var>request</var>'s <a for=request>current URL</a>'s <a for=url>path</a>,
|httpOnlyAllowed|,
|sameSite|,
|partitionKey|
and |partitionedContext|.

<p class=note>It is expected that the cookie store returns an ordered list of cookies
<li>If |cookies| <a for="list">is empty</a>, then return.
<li>Let |value| be the result of running <a>serialize cookies</a> given |cookies|.
<li><a for="header list">Append</a> (`<code>Cookie</code>`, <var>value</var>) to <var>request</var>'s <a for=request>header list</a>.
</ol>
</div>

<div algorithm>
<p>To <dfn>determine the same-site mode</dfn> for a given <a for=/>request</a> <var>request</var>, run these steps:
<ol>
<li><p><a for=/>Assert</a>: <var>request</var>'s <a for=request>method</a> is "GET" or "POST".
<li><p>If <var>request</var>'s <a for=request>method</a> is "GET" and
<var>request</var>'s <a for=request>destination</a> is "document", return "LaxOrLess".
<p class=XXX>TODO: This needs to describe Lax-Allowing-Unsafe quirks
<li><p>If <var>request</var>'s <a for=request>client</a>'s has cross-site ancestor is true, return "None".
<p class=XXX>TODO: This refers to the cross-site ancestor flag added in https://github.com/whatwg/html/pull/8036
<li><p>If <var>request</var>'s <a for=request>redirect-taint</a> is "Cross-Site", return "None".
<p class=XXX>Should we default to "UnsetOrLess" in place of "None", i.e. is "None" or "Lax" the default for us?
<li><p>Return "StrictOrLess".
</ol>
</div>

<div algorithm>
<p>To <dfn>compute the cookie partition key</dfn> for a given <a for=/>request</a> <var>request</var>, run these steps:
<p class=XXX>See https://dcthetall.github.io/CHIPS-spec/draft-cutler-httpbis-partitioned-cookies.html#name-computing-the-cookie-partit
<ol>
<li><p>Let <var>topLevelOrigin</var> be <var>request</var>'s <a for=request>client</a>'s
<a for="environment">top-level origin</a>.

<li><p>Let <var>topLevelSite</var> be the result of <a lt="obtain a site">obtaining a site</a>,
given <var>topLevelOrigin</var>.

<li>
<p>Let <var>crossSiteAncestors</var> be <var>request</var>'s <a for=request>client</a>'s has cross-site ancestor.

<li><p>Return (<var>topLevelSite</var>, <var>crossSiteAncestors</var>).
</ol>
</div>

<div algorithm>
<p>To <dfn>determine the partitioned context state</dfn> for a given <a for=/>request</a> <var>request</var>, run these steps:
<ol>
<li><p>If <var>request</var>'s <a for=request>client</a>'s has cross-site ancestor is false, return false.
<p class=XXX>TODO: This refers to the cross-site ancestor flag added in https://github.com/whatwg/html/pull/8036
<li><p>If <var>request</var>'s <a for=request>client</a>'s [=environment/has storage access=] is true, return false.
<p class=XXX>TODO: This refers to the flag added in https://privacycg.github.io/storage-access/#environment-has-storage-access
<li><p>Return true.
</ol>
</div>

<h3 id=origin-header>`<code>Origin</code>` header</h3>

<p>The `<dfn export http-header id=http-origin><code>Origin</code></dfn>`
Expand Down Expand Up @@ -4652,9 +4745,12 @@ steps:
<!-- If you are ever tempted to move this around, carefully consider responses from about URLs,
blob URLs, service workers, HTTP cache, HTTP network, etc. -->

<li><p>If <var>request</var> has a <a for=request>redirect-tainted origin</a>, then set
<li><p>If <var>request</var>'s <a for=request>redirect-taint</a> is not "<code>None</code>", then set
<var>internalResponse</var>'s <a for=response>has-cross-origin-redirects</a> to true.

<li><p>If <var>request</var>'s <a for=request>redirect-taint</a> is "<code>Cross-Site</code>", then set
<var>internalResponse</var>'s <a for=response>has-cross-site-redirects</a> to true.

<li><p>If <var>request</var>'s <a for=request>timing allow failed flag</a> is unset, then set
<var>internalResponse</var>'s <a for=response>timing allow passed flag</a>.

Expand Down Expand Up @@ -5652,23 +5748,8 @@ run these steps:

<li>
<p>If <var>includeCredentials</var> is true, then:

<ol>
<li>
<p>If the user agent is not configured to block cookies for <var>httpRequest</var> (see
<a href=https://httpwg.org/specs/rfc6265.html#privacy-considerations>section 7</a> of
[[!COOKIES]]), then:

<ol>
<li><p>Let <var>cookies</var> be the result of running the "cookie-string" algorithm (see
<a href=https://httpwg.org/specs/rfc6265.html#cookie>section 5.4</a> of
[[!COOKIES]]) with the user agent's cookie store and <var>httpRequest</var>'s
<a for=request>current URL</a>.

<li>If <var>cookies</var> is not the empty string, then <a for="header list">append</a>
(`<code>Cookie</code>`, <var>cookies</var>) to <var>httpRequest</var>'s
<a for=request>header list</a>.
</ol>
<li><p><a>Append a request `<code>Cookie</code>` header</a> for <var>httpRequest</var>.

<li>
<p>If <var>httpRequest</var>'s <a for=request>header list</a>
Expand Down