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

Add Third-Party Cookie Deprecation Heuristics to Web Compat #253

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from
144 changes: 144 additions & 0 deletions compatibility.bs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,21 @@ urlPrefix: https://drafts.fxtf.org/css-masking-1/
urlPrefix: https://drafts.csswg.org/css-values-3/
type: dfn
text: dppx; url: #dppx
urlPrefix: https://html.spec.whatwg.org/multipage/
urlPrefix: document-sequences.html
type: dfn
for: browsing context
text: is popup
text: opener browsing context
text: opener origin at creation
urlPrefix: https://privacycg.github.io/nav-tracking-mitigations/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be a tough sell for a WHATWG standard to accept. If this doesn't fly then maybe we could move this PR to a more local spec? Curious what @miketaylr would think.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The link targets here are an extra field on HTML's top-level traversable. Part of merging this PR might be to merge that field into HTML. (Merging it into Compat is also possible, but I believe the bounce tracking record is intended to be more permanent than the heuristics in this PR.)

type: dfn
for: top-level traversable
text: bounce tracking record; url: top-level-traversable-bounce-tracking-record
for: bounce tracking record
text: initial host; url: #bounce-tracking-record-initial-host
text: bounce set; url: #bounce-tracking-record-bounce-set
text: user activation set; url: #bounce-tracking-record-user-activation-set
</pre>

<pre class="biblio">
Expand All @@ -67,9 +82,11 @@ spec:css-display-3; type:value; for:display; text:flex
spec:css-flexbox-1; type:value; text:inline-flex
spec:css-syntax-3; type:dfn; text:invalid
spec:filter-effects-1; type:property; text:filter
spec:infra; type:dfn; text:list
spec:infra; type:dfn; text:user agent
spec:svg2; type:dfn; text:fill
spec:svg2; type:dfn; text:stroke
spec:url; type:dfn; for:url; text:host
</pre>

<!-- Commented out until we know what the heck to put here:
Expand Down Expand Up @@ -836,6 +853,133 @@ supported on all {{Window}} objects and <code><{body}></code> elements as attrib
</tbody>
</table>

<h2 id="sa-heuristics-section">Cookie Access Heuristics</h2>

User agents are blocking third-party cookies by default while avoiding user-facing
breakage by removing support for common web patterns, particularly login flows via
third-party identity providers. Browsers should follow the established patterns in
this specification in order to provide short-term cookie access to unbreak these flows.

<h3 id="sa-heuristics-global-data">Global Data</h3>

A <dfn>site pair</dfn> is a [=tuple=] consisting of a [=site=] <dfn for=site pair>third party site</dfn>
and a [=site=] <dfn for=site pair>first party site</dfn>

The user agent holds a <dfn>heuristic grants map</dfn> which is a [=map=] of [=site pairs=] to
[=moments=]. The [=moment=] represents the expiration timestamp of a cookie access grant
for [=third party site=] on [=first party site=].

<h3 id="sa-heuristics-constants">Constants</h3>

The <dfn>popup heuristic grant duration</dfn> is an [=implementation-defined=]
[=duration=] that represents the length of time after the popup heuristic is
triggered that a user agent will store the corresponding popup heuristic grant
in its [=heuristic grants map=].

Note: Most implementations use 30 days as the [=popup heuristic grant duration=].

The <dfn>redirect heuristic grant duration</dfn> is an [=implementation-defined=]
[=duration=] that represents the length of time after the redirect heuristic is
triggered that a user agent will store the corresponding redirect heuristic grant
in its [=heuristic grants map=].

Note: Most implementations use 15 minutes as the [=redirect heuristic grant duration=].

<h3 id="sa-heuristics-access-grant">Cookie Access Grant</h3>

<div algorithm>

To <dfn>grant access for heuristics</dfn> given a [=site=] |site|, [=site=]
|firstPartySite|, [=moment=] |currentWallTime|, and [=duration=] |duration|,
perform the following steps:

1. Let |key| be a [=site pair=] with [=third party site=] set to |site| and
[=first party site=] set to |firstPartySite|.
1. Let |expirationTime| be |duration| after |currentWallTime|.
1. Set [=heuristic grants map=][|key|] to |expirationTime|.

</div>

<h3 id="sa-heuristics-access">Cookie Access Monkey Patch</h3>

Issue: TODO: add monkey patch to network fetch cookie access that reads from [=heuristic grants map=].

<h3 id="sa-heuristics-popup">Popup Heuristic</h3>

Append the following steps to the [[!HTML]]'s <a spec="html">activation notification</a> algorithm:

<div algorithm="user-activation-patch">

1. Run [=detect a popup heuristic=] given <var ignore>document</var>.

</div>

<div algorithm>

To <dfn>detect a popup heuristic</dfn> given a [=Document=] |document|,
perform the following steps:

1. Let |browsingContext| be |document|'s [=Document/browsing context=].
1. If |browsingContext|'s [=browsing context/is popup=] is false, then return.
1. If |browsingContext|'s [=browsing context/opener browsing context=] is null, then return.
1. If |browsingContext|'s [=browsing context/opener origin at creation=] is null, then return.
1. Let |firstPartySite| be the result of running [=obtain a site=] given the |browsingContext|'s
[=browsing context/opener origin at creation=].
1. Let |navigable| be |document|'s [=node navigable=].
1. If |navigable| is null, then return.
1. Let |topDocument| be |navigable|'s [=navigable/top-level traversable=]'s
[=navigable/active document=].
1. Let |origin| be |topDocument|'s [=Document/origin=].
1. If |origin| is an [=opaque origin=] then return.
1. Let |site| be the result of running [=obtain a site=] given |origin|.
1. Let |currentWallTime| be |topDocument|'s [=relevant settings object=]'s
[=environment settings object/current wall time=].
1. [=Grant access for heuristics=] given |site|, |firstPartySite|, |currentWallTime|, and
[=popup heuristic grant duration=].

Issue(amaliev/3pcd-exemption-heuristics#3): TODO: Consider whether to check for third-party iframe initiators.

</div>

<h3 id="sa-heuristics-redirect">Redirect Heuristic</h3>

Insert the following steps at the start of [[!HTML]]'s <a spec="html">load a document</a> algorithm.

<div algorithm="loading-a-document-patch">

1. Run [=detect a redirect heuristic=] given <var ignore>navigationParams</var>'s <var ignore>navigable</var>.

</div>

<div algorithm>

To <dfn>detect a redirect heuristic</dfn> given a [=/navigable=] |navigable|, perform the following
steps:

1. Let |topDocument| be |navigable|'s [=navigable/top-level traversable=]'s
[=navigable/active document=].
1. Let |firstPartyOrigin| be |topDocument|'s [=Document/origin=].
1. If |firstPartyOrigin| is an [=opaque origin=] then return.
1. Let |firstPartySite| be the result of running [=obtain a site=] given |firstPartyOrigin|.
1. Let |bounceTrackingRecord| be |navigable|'s [=navigable/top-level traversable=]'s
[=top-level traversable/bounce tracking record=].
1. Let |currentWallTime| be |topDocument|'s [=relevant settings object=]'s
[=environment settings object/current wall time=].
1. Let |navigatedUrlsSet| be |bounceTrackingRecord|'s [=bounce tracking record/bounce set=].
1. Append |bounceTrackingRecord|'s [=bounce tracking record/initial host=] to |navigatedUrlsSet|.
1. [=list/For each=] |bounceUrl| in |navigatedUrlsSet|:
1. Let |site| be the result of running [=obtain a site=] given |bounceUrl|.
1. If |site| is [=site/same site=] to |firstPartySite|, [=iteration/continue=].
1. If |bounceTrackingRecord|'s [=bounce tracking record/user activation set=] does not contain |site|,
[=iteration/continue=].
<!-- TODO: Check that the user visited |firstPartySite| before |site|, to verify the
[A-B-A flow](https://github.com/amaliev/3pcd-exemption-heuristics/blob/main/explainer.md#scenario-c2).
This will require traversing the navigable's history. -->
1. [=Grant access for heuristics=] given |site|, |firstPartySite|, |currentWallTime|, and
[=redirect heuristic grant duration=].

</div>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a description of how this impacts the (admittedly underspecified) cookie computation in Fetch like in https://privacycg.github.io/nav-tracking-mitigations/#bounce-tracking-mitigations-network-cookie-write-monkey-patch

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a new section with a TODO for now. Will update soon.

<h2 id="ua-string-section">The User-Agent String</h2>

The <code>User-Agent</code> header field syntax is formally defined by [[!HTTP-SEMANTICS]] and
Expand Down
Loading