Safari

Current status

Detail Description
Mechanism Intelligent Tracking Prevention 2.3
Originally deployed in Safari 13 in iOS 13, macOS Catalina, Mojave, and High Sierra
Latest update Documented 10 Dec 2019
Latest update includes
  • All cross-site request referrer headers are downgraded to origin
  • Cookie access blocked from all third-party requests where the domain has not received user interaction in first-party context
User controls ITP doesn't let users control how it works. Users can simply toggle ITP off by unchecking “Prevent cross-site tracking” in Safari's Security preferences.

Privacy controls in Safari

Classification of “known trackers”

Safari classifies domains capable of cross-site tracking using an algorithm that runs on-device. Thus each Safari user has a potentially different list of domains that are blocked from having access to browser storage.

The algorithm is superficially described in this blog post:

A machine learning model is used to classify which top privately-controlled domains have the ability to track the user cross-site, based on the collected statistics. Out of the various statistics collected, three vectors turned out to have strong signal for classification based on current tracking practices: subresource under number of unique domains, sub frame under number of unique domains, and number of unique domains redirected to. All data collection and classification happens on-device.

If a domain is classified by Safari as having cross-site tracking capabilities, it will have several restrictions placed upon it, listed below.

Example: A website loads an iframe from www.iframe-domain.com. This is the first time the user's browser has loaded content from this domain in a frame. ITP does not yet react to this, as it's a single occurrence. Later, the user visits multiple different websites, all loading data from the same domain into an iframe. At this point, ITP classifies the domain as having cross-site capabilities, and the restrictions listed on this page will be put into effect.

To monitor the list of domains classified by your Safari instance, or to test ITP in action, you can utilize the ITP Debug Mode, with instructions for use found behind this link.

Third-party cookies

Safari has a number of different approaches to blocking third-party cookie access.

First, there's Safari's default cookie policy, which has been active since as early as 2003. The default policy prevents domains of a third-party site from setting cookies if the site hasn't already been “seeded” with a cookie in first-party context. This policy is always in place, and can not be circumvented with e.g. the Storage Access API (see below).

Example: The user visits a website which sends a request to www.third-party-domain.com, which subsequently attempts to set a cookie in the HTTP response. Safari blocks this, as the user's browser has no cookies set on www.third-party-domain.com yet. If the user were to visit www.third-party-comain.com in first-party context (actually typing the URL in the browser omnibox), by setting a cookie in first-party context would relax this default cookie policy for this particular site in future third-party requests.

Second, Safari blocks all third-party requests on a site from accessing cookies if the site has not received user interaction in the first-party context (i.e. with the URL in the address bar) in the last 30 days of Safari use.

Example: The user visits www.site-example.com. Until the user interacts with the site (click, tap, text input), no third-party domain will have access to its cookies. If the user interacts with the site, then third-party requests will have storage access for the next 30 days of Safari use (unless other policies block such access).

Finally, if the domain is classified as having cross-site tracking capabilities, third-party cookie access is blocked.

If the browser wants to access cookies on third-party domains classified by ITP, it needs to utilize the Storage Access API to prompt the user whether it is OK to share data with the third-party domain.

Storage Access API

Safari introduced the Storage Access API in February 2018. With the Storage Access API, a website can ask the user's permission to access storage in an embedded cross-site resource which would otherwise have its cookie access restricted.

This will not allow access to cookies blocked by Safari's default cookie policy.

To be able to use the Storage Access API, the embedded site must have been interacted with in first-party context (URL in address bar) in the last 30 days of Safari use.

Example: The user is on www.blog-site.com, which loads a comment service in an <iframe> from www.comment-service.com. Since this is a cross-site resource load, ITP will not allow access to the site due to the site not having prior cookies set (Safari's default cookie policy), and because the user hasn't interacted with the site in first-party context in the last 30 days of Safari use.

Requesting storage access via the API

If the user has interacted with the embedded site in first-party context in the last 30 days of Safari use, and the site has cookies set, the site can call the Storage Access API upon a user interaction in the embed (such as a click or tap), after which Safari will prompt the user if they want to allow the embedded site to access its storage.

Example: The user visits www.comment-service.com, and logs into the service. The service sets a cookie in first-party context to save the user's login state. Then, the user browses to www.blog-site.com, which embeds www.comment-service.com in an <iframe>. In the <iframe>, the user clicks a button which initiates a login state check on www.comment-service.com. This time, www.comment-service.com uses the Storage Access API, and the user is prompted if they want to allow www.comment-service.com to access its first-party storage. If the user allows it, the embedded site will have access to its cookies, even though it is running in a third-party context.

If the user doesn't interact with the site again in first-party context in 30 days of Safari use, Safari will clear all storage from the embedded site, and prevent any new storage from being set. This will continue until the user interacts with the site in first-party context again.

Note that successful use of the Storage Access API (either clicking “Allow” on the prompt, or interacting with the embed after having clicked “Allow” previously) is interpreted as interaction in first-party context, which means the 30 day timer is reset in such scenarios! This allows the embed to keep accessing its first-party storage even if the user doesn't visit the embedded site in first-party context.

First-party cookies

For first-party cookies set with JavaScript's document.cookie API, maximum expiration is set to 7 days.

If the referring domain is a known tracker, and if the URL has query parameters (?key=value) or fragments (#somevalue), cookies set with JavaScript's document.cookie API have a maximum expiration of 24 hours.

Example: The user follows a link from www.facebook.com (a known tracking domain), and lands on the website. Facebook appends an ?fbclid=123123123123 parameter to the URL. Because the referring URL is on a classified domain, and because the landing page has a query parameter, ITP sets a maximum expiration of 24 hours to any cookies set with JavaScript while on that landing page.

First-party cookies set with the Set-Cookie HTTP response header are not impacted by ITP, and have no restrictions placed on their expiration.

Other third-party storage

localStorage is partitioned, so that access is keyed to the combination of the source and target domains. Thus www.domain.com has a different localStorage store in third-party context when accessed from www.domain1.com and from www.domain2.com. This partitioned store is also cleared between application launches.

IndexedDB is restricted.

sessionStorage has no restrictions.

Other first-party storage

If the referring domain is a known tracker, and if the URL has query parameters (?key=value) or fragments (#somevalue), then all non-cookie website storage in first-party context is restricted to maximum 7 days lifetime since the last user interaction (click, tap, or text input) with the site.

Example: The user clicks a link on www.known-tracker.com (a classified domain), and the landing page URL is appended with the fragment #abcd1234. ITP sets the maximum lifetime of all non-cookie website storage (e.g. localStorage) to 7 days, and the timer starts from the first interaction with the site. If the user doesn't interact with the site again for 7 days, all non-cookie storage is deleted.

If there is no user interaction with the first-party site, this type of storage is expired within few seconds.

Referrer

Safari downgrades referrers for all non-navigational cross-site requests to their origin. Thus if a page on https://www.domain.com/page/page.html tried to load an image from https://images.imagecdn.com, the referer header would show https://www.domain.com rather than the full referrer.

Furthermore, if the referring domain is a known tracker, and if the referring page has query parameters (?key=value) or fragments (#somevalue), the document.referrer property is downgraded to effective top-level domain plus one part (eTLD+1). Thus a request originating from https://sub.classified.domain.com/page?userId=abcd1234 would end up as https://domain.com in the document.referrer property of the landing page.

For navigational requests, no-referrer-when-downgrade applies.