From a414a12e2aec90a80fcdba0d47fef1012c1cace4 Mon Sep 17 00:00:00 2001 From: Anton Maliev Date: Thu, 16 Nov 2023 21:23:31 +0000 Subject: [PATCH 01/12] heuristics spec start --- compatibility.bs | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/compatibility.bs b/compatibility.bs index 3bda92d..ceb0e03 100644 --- a/compatibility.bs +++ b/compatibility.bs @@ -67,9 +67,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:html; type:dfn; for:/; text:top-level traversable 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 + 1. [=Grant access for heuristics=] given:
host
From 5d58b6438d66259b1b2fd15e6f257c0d1d865c04 Mon Sep 17 00:00:00 2001 From: Anton Maliev Date: Fri, 8 Dec 2023 04:07:27 +0000 Subject: [PATCH 05/12] intro wording changes --- compatibility.bs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/compatibility.bs b/compatibility.bs index 4eef9b4..e411f8f 100644 --- a/compatibility.bs +++ b/compatibility.bs @@ -841,26 +841,26 @@ supported on all {{Window}} objects and <{body}> elements as attrib

Storage Access Heuristics

-Browsers are working to deprecate third-party cookies while avoiding user-facing +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 can observe Storage access heuristics -from the user in order to provide short-term storage access to unbreak these flows. - -The following spec represents the Chromium implementation of this feature. +third-party identity providers. Browsers should follow the established patterns in +this specification in order to provide short-term storage access to unbreak these flows.

Constants

The popup heuristic grant duration is an [=implementation-defined=] [=duration=] that represents the length of time after the popup heuristic is -detected that the popup [=host=] will have access to the opener [=host=]. +triggered that a user agent will store the corresponding [=popup heuristic grant=] +in its [=heuristic grants map=]. -Note: 30 days is a reasonable [=popup heuristic grant duration=] value. +Note: Most implementations use 30 days as the [=popup heuristic grant duration=]. The redirect heuristic grant duration is an [=implementation-defined=] [=duration=] that represents the length of time after the redirect heuristic is -detected that the bounced [=host=] will have access to the final [=host=]. +triggered that a user agent will store the corresponding [=redirect heuristic grant=] +in its [=heuristic grants map=]. -Note: 15 minutes is a reasonable [=redirect heuristic grant duration=] value. +Note: Most implementations use 15 minutes as the [=redirect heuristic grant duration=].

Storage Access Grant

From c875c3bc8fefa1bca97821e55e9ed2d47cbce962 Mon Sep 17 00:00:00 2001 From: Dominic Farolino Date: Mon, 4 Dec 2023 17:13:35 -0500 Subject: [PATCH 06/12] Reference top-level traversable correctly --- compatibility.bs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/compatibility.bs b/compatibility.bs index e411f8f..f82fe20 100644 --- a/compatibility.bs +++ b/compatibility.bs @@ -67,7 +67,6 @@ 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:html; type:dfn; for:/; text:top-level traversable spec:infra; type:dfn; text:list spec:infra; type:dfn; text:user agent spec:svg2; type:dfn; text:fill @@ -914,7 +913,7 @@ perform the following steps: 1. If |browsingContext|'s opener origin at creation is null, then abort these steps. 1. Let |navigable| be |document|'s [=node navigable=]. 1. If |navigable| is null, then abort these steps. -1. Let |topDocument| be |navigable|'s [=top-level traversable=]'s +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 abort these steps. @@ -944,13 +943,13 @@ before Step 5, "Return null", which is the point that the [=document=] is loaded To detect a redirect heuristic given a navigable |navigable|, perform the following steps: -1. Let |topDocument| be |navigable|'s [=top-level traversable=]'s +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 abort these steps. 1. Let |firstPartySite| be the result of running [=obtain a site=] given |firstPartyOrigin|. 1. Let |firstPartyHost| be |firstPartySite|'s [=host=]. -1. Let |bounceTrackingRecord| be |navigable|'s [=top-level traversable=]'s bounce tracking record. +1. Let |bounceTrackingRecord| be |navigable|'s [=navigable/top-level traversable=]'s bounce tracking record. 1. [=list/For each=] |bounceUrl| in |bounceTrackingRecord|'s bounce set: 1. Let |bounceSite| be the result of running [=obtain a site=] given |bounceUrl|. 1. Let |bounceHost| be |bounceSite|'s [=host=]. From 3b10ef830334c6a577c64819e278a68202a3fbec Mon Sep 17 00:00:00 2001 From: Dominic Farolino Date: Mon, 4 Dec 2023 17:19:48 -0500 Subject: [PATCH 07/12] User activation reference --- compatibility.bs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/compatibility.bs b/compatibility.bs index f82fe20..11932d6 100644 --- a/compatibility.bs +++ b/compatibility.bs @@ -897,12 +897,14 @@ This algorithm is based on [=request permission to use=], except for the followi

Popup Heuristic

-Append the following steps to the activation notification -steps in the [[HTML#user-activation-processing-model|user activation processing -model]]: +Append the following steps to the [[!HTML]]'s activation notification algorithm: + +
1. Run [=detect a popup heuristic=] given document. +
+
To detect a popup heuristic given a [=Document=] |document|, From c56b58e0849a8c80aa5303e760d5c132fbc6059a Mon Sep 17 00:00:00 2001 From: Dominic Farolino Date: Mon, 4 Dec 2023 17:30:09 -0500 Subject: [PATCH 08/12] Opener origin at creation time --- compatibility.bs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/compatibility.bs b/compatibility.bs index 11932d6..ba69061 100644 --- a/compatibility.bs +++ b/compatibility.bs @@ -42,6 +42,12 @@ 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 origin at creation
@@ -911,14 +917,14 @@ To detect a popup heuristic given a [=Document=] |document|,
 perform the following steps:
 
 1. Let |browsingContext| be |document|'s [=Document/browsing context=].
-1. If |browsingContext|'s is popup is false, then abort these steps.
-1. If |browsingContext|'s opener origin at creation is null, then abort these steps.
+1. If |browsingContext|'s [=browsing context/is popup=] is false, then return.
+1. If |browsingContext|'s [=browsing context/opener origin at creation=] is null, then return.
 1. Let |navigable| be |document|'s [=node navigable=].
-1. If |navigable| is null, then abort these steps.
+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 abort these steps.
+1. If |origin| is an [=opaque origin=] then return.
 1. Let |site| be the result of running [=obtain a site=] given |origin|.
 1. Let |host| be |site|'s [=host=].
 1. [=Grant access for heuristics=] given:

From bfbe0a83465bcbc8b56b601f239afda20d9fdab0 Mon Sep 17 00:00:00 2001
From: Dominic Farolino 
Date: Mon, 4 Dec 2023 18:19:31 -0500
Subject: [PATCH 09/12] Bounce tracking traversable

---
 compatibility.bs | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/compatibility.bs b/compatibility.bs
index ba69061..04b212e 100644
--- a/compatibility.bs
+++ b/compatibility.bs
@@ -48,6 +48,12 @@ urlPrefix: https://html.spec.whatwg.org/multipage/
       for: browsing context
         text: is popup
         text: opener origin at creation
+urlPrefix: https://privacycg.github.io/nav-tracking-mitigations/
+  type: dfn
+    for: top-level traversable
+      text: bounce tracking record; url: top-level-traversable-bounce-tracking-record
+    for: bounce tracking record
+      text: bounce set; url: #bounce-tracking-record-bounce-set
 
@@ -941,24 +947,28 @@ perform the following steps:
 
 

Redirect Heuristic

-Insert the following steps in the load a document algorithm, -before Step 5, "Return null", which is the point that the [=document=] is loaded. +Insert the following steps in [[!HTML]]'s load a document algorithm, before the +final step which returns null. + +
1. Run [=detect a redirect heuristic=] given navigable. +
+
-To detect a redirect heuristic given a navigable |navigable|, -perform the following steps: +To detect a redirect heuristic 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 abort these steps. +1. If |firstPartyOrigin| is an [=opaque origin=] then return. 1. Let |firstPartySite| be the result of running [=obtain a site=] given |firstPartyOrigin|. 1. Let |firstPartyHost| be |firstPartySite|'s [=host=]. -1. Let |bounceTrackingRecord| be |navigable|'s [=navigable/top-level traversable=]'s bounce tracking record. -1. [=list/For each=] |bounceUrl| in |bounceTrackingRecord|'s bounce set: +1. Let |bounceTrackingRecord| be |navigable|'s [=navigable/top-level traversable=]'s [=top-level traversable/bounce tracking record=]. +1. [=list/For each=] |bounceUrl| in |bounceTrackingRecord|'s [=bounce tracking record/bounce set=]: 1. Let |bounceSite| be the result of running [=obtain a site=] given |bounceUrl|. 1. Let |bounceHost| be |bounceSite|'s [=host=]. 1. If |bounceHost| [=host/equals=] |firstPartyHost|, [=iteration/continue=]. From a8c9ecfa0c6884bc5a243fa23043aca05fa0b896 Mon Sep 17 00:00:00 2001 From: Anton Maliev Date: Fri, 8 Dec 2023 05:09:55 +0000 Subject: [PATCH 10/12] Use global map instead of permissions API, plus various fixes --- compatibility.bs | 104 +++++++++++++++++++++-------------------------- 1 file changed, 46 insertions(+), 58 deletions(-) diff --git a/compatibility.bs b/compatibility.bs index 04b212e..9b2c8f4 100644 --- a/compatibility.bs +++ b/compatibility.bs @@ -47,6 +47,7 @@ urlPrefix: https://html.spec.whatwg.org/multipage/ 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/ type: dfn @@ -850,63 +851,57 @@ supported on all {{Window}} objects and <{body}> elements as attrib -

Storage Access Heuristics

+

Cookie Access Heuristics

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 storage access to unbreak these flows. +this specification in order to provide short-term cookie access to unbreak these flows. + +

Global Data

+ +A site pair is a [=tuple=] consisting of a [=site=] third party site +and a [=site=] first party site + +The user agent holds a heuristic grants map 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=].

Constants

The popup heuristic grant duration 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=] +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 redirect heuristic grant duration 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=] +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=]. -

Storage Access Grant

- -Define a [=powerful feature=] identified by the [=powerful feature/name=] -"storage-access-heuristics", with the following permission key type: - -A [=permission key=] of the "storage-access-heuristics" feature is a [=tuple=] consisting -of a [=host=] top-level and a [=host=] requester. +

Cookie Access Grant

-To grant access for heuristics given a [=host=] |host|, [=host=] -|firstPartyHost|, and [=duration=] |duration|, perform the following steps: - -1. Let |key| be a [=permission key=] with top-level set to |firstPartyHost| - and requester set to |host|. -1. Queue a task on the [=current settings object=]'s [=responsible event loop=] to: - 1. [=Set a permission store entry=] with: -
-
descriptor
-
"storage-access-heuristics"
-
key
-
|key|
-
current state
-
"granted"
-
- 2. Set the new permission's [=permission/lifetime=] to |duration|. - -
-This algorithm is based on [=request permission to use=], except for the following key differences: -- It sets a dynamic permission [=permission/lifetime=]. -- It generates a [=permission key=] independently of the [=current settings object=].
+To grant access for heuristics 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|.
+

Cookie Access Monkey Patch

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

Popup Heuristic

Append the following steps to the [[!HTML]]'s activation notification algorithm: @@ -924,7 +919,10 @@ 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 @@ -932,16 +930,12 @@ perform the following steps: 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 |host| be |site|'s [=host=]. -1. [=Grant access for heuristics=] given: -
-
host
-
|host|
-
firstPartyHost
-
|browsingContext|'s opener origin at creation=
-
duration
-
[=popup heuristic grant duration=]
-
+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.
@@ -966,23 +960,17 @@ steps: 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 |firstPartyHost| be |firstPartySite|'s [=host=]. -1. Let |bounceTrackingRecord| be |navigable|'s [=navigable/top-level traversable=]'s [=top-level traversable/bounce tracking record=]. +1. Let |bounceTrackingRecord| be |navigable|'s [=navigable/top-level traversable=]'s + [=top-level traversable/bounce tracking record=]. 1. [=list/For each=] |bounceUrl| in |bounceTrackingRecord|'s [=bounce tracking record/bounce set=]: - 1. Let |bounceSite| be the result of running [=obtain a site=] given |bounceUrl|. - 1. Let |bounceHost| be |bounceSite|'s [=host=]. - 1. If |bounceHost| [=host/equals=] |firstPartyHost|, [=iteration/continue=]. - - - 1. [=Grant access for heuristics=] given: -
-
host
-
|bounceHost|
-
firstPartyHost
-
|firstPartyHost|
-
duration
-
[=redirect heuristic grant duration=]
-
+ 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. 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 + [=redirect heuristic grant duration=].
From fd755600c4df6c1940e3e5d9e570cf7eeb5f2a0b Mon Sep 17 00:00:00 2001 From: Anton Maliev Date: Tue, 22 Oct 2024 21:39:30 +0000 Subject: [PATCH 11/12] address redirect comments --- compatibility.bs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/compatibility.bs b/compatibility.bs index 9b2c8f4..15b74fc 100644 --- a/compatibility.bs +++ b/compatibility.bs @@ -54,7 +54,9 @@ urlPrefix: https://privacycg.github.io/nav-tracking-mitigations/ 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
@@ -962,15 +964,20 @@ steps:
 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. [=list/For each=] |bounceUrl| in |bounceTrackingRecord|'s [=bounce tracking record/bounce set=]:
-    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. 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
-    [=redirect heuristic grant duration=].
+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=].
+    
+    1. [=Grant access for heuristics=] given |site|, |firstPartySite|, |currentWallTime|, and
+        [=redirect heuristic grant duration=].
 
 
 

From cd438d225475e62de6efa8f519ca71cd42a90c63 Mon Sep 17 00:00:00 2001
From: Anton Maliev 
Date: Tue, 22 Oct 2024 22:04:12 +0000
Subject: [PATCH 12/12] Update monkey patch location in Load a Document

---
 compatibility.bs | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/compatibility.bs b/compatibility.bs
index 15b74fc..fba69d6 100644
--- a/compatibility.bs
+++ b/compatibility.bs
@@ -943,12 +943,11 @@ Issue(amaliev/3pcd-exemption-heuristics#3): TODO: Consider whether to check for
 
 

Redirect Heuristic

-Insert the following steps in [[!HTML]]'s load a document algorithm, before the -final step which returns null. +Insert the following steps at the start of [[!HTML]]'s load a document algorithm.
-1. Run [=detect a redirect heuristic=] given navigable. +1. Run [=detect a redirect heuristic=] given navigationParams's navigable.