Today we’re happy to bring you Intelligent Tracking Prevention 2.0, or ITP 2.0. It builds upon ITP 1.0, which we released last year, and ITP 1.1, which was released in March, adding the Storage Access API.
Removal of the 24 Hour Cookie Access Window
ITP 2.0, as opposed to earlier versions, immediately partitions cookies for domains determined to have tracking abilities. The previous general cookie access window of 24 hours after user interaction has been removed. Instead, authenticated embeds can get access to their first-party cookies through the Storage Access API. The API requires that the user interacts with the embedded content.
Example
video.example offers an ad-free subscription service and has many of its videos embedded on other websites. ITP classifies video.example as having tracking abilities and therefore partitions its cookies. This is a timeline of how ITP might work for video.example:
- Day 1: The user logs in to video.example which updates video.example’s user interaction timestamp.
- Day 22: The user clicks to watch a video.example clip on news.example and the embedded video calls the Storage Access API. ITP notes that the user has not previously granted video.example access to its first-party cookies on news.example and thus prompts the user. The user grants storage access and video.example’s user interaction timestamp is updated.
- Day 26: The user clicks to watch another video.example clip on news.example and the video.example embed calls the Storage Access API. ITP notes that the user has previously granted video.example access to its first-party cookies on news.example and thus provides access without a prompt and updates video.example’s user interaction timestamp.
- Day 55: The user interacts with video.example as first party website which updates video.example’s user interaction timestamp.
- Day 76: The user clicks to watch a video.example clip on blog.example and the video.example embed calls the Storage Access API. ITP notes that the user has not previously granted video.example access to its first-party cookies on blog.example and thus prompts the user. The user grants storage access and video.example’s user interaction timestamp is updated.
- Day 80-82: The user doesn’t use Safari which means that these three days do not count towards the 30 days before website data purge.
- Day 109: video.example’s cookies, website data, and granted storage access entries are purged as a result of 30 days of Safari usage without an update to video.example’s user interaction timestamp.
Developer Advice
If you are a provider of authenticated third-party content, you should adopt the Storage Access API. If your website relies on a third party domain for user authentication, your authentication provider should adopt the Storage Access API or transfer authentication tokens to you in URLs.
User Prompt For the Storage Access API
ITP 2.0 adds a prompt to WebKit’s implementation of the Storage Access API. If the user allows access, their choice is persisted. If the user declines, their choice is not persisted which allows them to change their mind if they at a later point tap a similar embedded widget that calls the Storage Access API.
As an example, video.example may have an ad-free subscription service and have many of its videos embedded on other websites. ITP will thus classify video.example as having tracking abilities and partition its cookies. When the user taps or clicks to play a clip embedded on news.example, video.example can call the Storage Access API to check whether the user is a subscriber. The user will be prompted if they have not explicitly allowed access under news.example previously.
Storage Access API Prompt
This prompt provides users with a way to show intent (the tap/click enabling the API call) and provide consent (“Allow” in the prompt). If the user chooses “Allow,” their choice is persisted and subsequent calls to the Storage Access API by video.example embeds on news.example do not trigger a prompt. Instead a tap or click on the embed is enough for a successful API call. As always, ITP considers the eTLD+1 to be the “party,” so a user “Allow” for sub.video.example under sub.news.example will be valid for video.example and any of its subdomains under news.example or any of its subdomains.
Successful use of the Storage Access API now counts as user interaction with the third-party and refreshes the 30 days of use before ITP purges the third-party’s website data. By successful use we mean the user was either prompted right now and chose “Allow,” or had previously chosen “Allow.” The fact that successful Storage Access API calls now count as user interaction allows users to stay logged into services they rarely use as first party but keep using as embedded third parties.
Finally, we received developer feedback (thank you), saying it should be possible to do a popup should storage access be granted but it turns out the user is not logged in. Our original version of the Storage Access API would consume the user gesture and thus require another tap or click to do a login popup. Now, the third-party embed is allowed to do a popup in the resolve scope of the returned promise, like so:
<script>
function makeRequestWithUserGesture() {
var promise = document.requestStorageAccess();
promise.then(
function () {
// Storage access was granted.
// Check whether the user is logged in.
// If not, do a popup to log the user in.
},
function () {
// Storage access was denied.
}
);
}
</script>
<button onclick="makeRequestWithUserGesture()">Play video</button>
Developer Advice
We encourage you to adopt the Storage Access API if you provide authenticated embeds. The API’s prompt provides you with a way to extend your users’ authenticated sessions if ITP has classified your domain as having the ability to track the user. If ITP classifies your domain and you don’t adopt the API, your domain will be permanently blocked from accessing its first-party cookies in a third-party context.
Temporary Compatibility Fix: Automatic Storage Access for Popups
Many federated logins send authentication tokens in URLs or through the postMessage API, both of which work fine under ITP 2.0. However, some federated logins use popups and then rely on third-party cookie access once the user is back on the opener page. Some instances of this latter category stopped working under ITP 2.0 since domains with tracking abilities are permanently partitioned.
Our temporary compatibility fix is to detect such popup scenarios and automatically forward storage access for the third party under the opener page. Since popups require user interaction, the third party could just as well had called the Storage Access API instead.
Developer Advice
If you provide federated login services, we encourage you to first call the Storage Access API to get cookie access and only do a popup to log the user in or acquire specific consent. The Storage Access API provides a better user experience without new windows and navigations. We’d also like to stress that the compatibility fix for popups is a temporary one. Longterm, your only option will be to call the Storage Access API.
Protection Against First Party Bounce Trackers
ITP 2.0 has the ability to detect when a domain is solely used as a “first party bounce tracker,” meaning that it is never used as a third party content provider but tracks the user purely through navigational redirects.
Say the user clicks on a news.example link on the social.example website. Instead of navigating them straight to their destination news.example, they are rapidly navigated through trackerOne.example and trackerTwo.example before reaching news.example. Those two tracker domains can store information about the user’s browsing history in first party storage and cookies. ITP 2.0 detects such tracking behavior and treats those domains just like any other tracker, i.e. purges their website data.
Protection Against Tracker Collusion
Through our research, we found that cross-site trackers help each other identify the user. This is basically one tracker telling another tracker that “I think it’s user ABC,” at which point the second tracker tells a third tracker “Hey, Tracker One thinks it’s user ABC and I think it’s user XYZ.” We call this tracker collusion, and ITP 2.0 detects this behavior through a collusion graph and classifies all involved parties as trackers.
In the graph above, as soon as trackerSix.example is classified by ITP, all the domains that have redirected to trackerSix.example get classified too. That’s trackerTwo.example, trackerThree.example, and trackerFive.example. Then domains that have redirected to those get classified too, which covers the last two—trackerOne.example and trackerFour.example.
Developer Advice
Avoid making unnecessary redirects to domains that are likely to be classified as having tracking ability.
Origin-Only Referrer for Domains Without User Interaction
ITP’s purging of website data does not prevent trackers from receiving the so called referrer header which reveals the webpage the user is currently on. In ITP 2.0, the referrer, if there is one, is downgraded to just the page’s origin for third party requests to domains that have been classified as possible trackers by ITP and have not received user interaction.
Here’s an example of what we mean by this: Say the user visits https://store.example/baby-products/strollers/deluxe-navy-blue.html, and that page loads a resource from trackerOne.example. Before ITP 2.0, the request to trackerOne.example would contain the full referrer “https://store.example/baby/strollers/deluxe-stroller-navy-blue.html” which reveals a lot about the user to the third-party. With ITP 2.0, the referrer will be reduced to just “https://store.example/”.
For further reading on this subject, see Mozilla’s research on origin-only referrers.
FAQ
Does ITP differentiate between my subdomains?
No. ITP captures statistics and applies its rules for the effective top-level domain plus one, or eTLD+1. An eTLD is .com or .co.uk so an example of an eTLD+1 would be social.co.uk but not sub.social.co.uk (eTLD+2) or just co.uk (eTLD).
Does eTLD mean public suffix?
Yes. See the Public Suffix List.
Is there a way for users to whitelist my domain to be excepted from ITP’s rules?
No, there is no such whitelisting feature.
How does ITP classify a domain’s tracking abilities?
See the original ITP 1.0 blog post for details on the machine learning model.
My domain is not a tracker, but it gets classified by ITP. Is that a bug?
ITP does not rely on a centralized blacklist of known trackers. Instead, it captures per-domain (eTLD+1) statistics on-device and classifies each domain’s ability to track cross-site. If a domain has the ability to track the user cross-site, it’s subject to ITP’s cookie and website data rules.
Is it enough for users to visit my website to keep its cookies from being purged if my domain gets classified by ITP?
No, a mere visit does not suffice. The user has to interact with your website, meaning a tap, click, or form entry. In ITP 2.0, user granted access through the Storage Access API also counts as such user interaction.
How do I reset ITP or the domains I’ve allowed storage access for?
Clear your Safari history. Note that this gets rid of data that may be needed to reproduce an ITP issue. If you’re investigating a bug related to ITP, don’t clear your history before you’re done with that work.
I need to debug my website in regards to ITP. Are there specific developer tools?
We’re working on an ITP Debug Mode which will help you debug websites and capture data that’s useful when filing bugs on ITP. It will be announced on this blog.
Feedback and Bug Reports
Please report bugs through bugs.webkit.org and send feedback to our evangelist Jon Davis. If you have technical questions on how the feature works you can find me on Twitter @johnwilander.