From 410d64d3097c2d028d58cd8f8546d5c547ac8b96 Mon Sep 17 00:00:00 2001 From: Arthur Edelstein Date: Thu, 4 Apr 2024 11:31:41 -0700 Subject: [PATCH] fix ios page --- archive/issue84/ios-edge-preview.png | Bin 0 -> 87548 bytes archive/issue84/ios-edge.html | 3599 +++++++++++++++++++++ archive/issue84/ios-edge.json | 1 + archive/issue84/ios-preview.png | Bin 117057 -> 116078 bytes archive/issue84/ios.html | 4341 ++++++++++++++------------ archive/issue84/ios.json | 2 +- ios-edge-preview.png | Bin 88121 -> 87548 bytes ios-edge.html | 791 +++-- ios-edge.json | 2 +- ios-preview.png | Bin 117057 -> 116078 bytes ios.html | 4341 ++++++++++++++------------ ios.json | 2 +- 12 files changed, 8703 insertions(+), 4376 deletions(-) create mode 100644 archive/issue84/ios-edge-preview.png create mode 100644 archive/issue84/ios-edge.html create mode 100644 archive/issue84/ios-edge.json diff --git a/archive/issue84/ios-edge-preview.png b/archive/issue84/ios-edge-preview.png new file mode 100644 index 0000000000000000000000000000000000000000..656941b4db698a0755ec7ebfef2588eb848ae9e4 GIT binary patch literal 87548 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 z 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≪eA`(CI_d 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

Tw^l}IY~yxhR@D;ny*j@e7v6dK#gWt6J?b@Gf5 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 + + + + + + + + + + What are the best private browsers on iOS in 2024? + + + + + +

+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

+
iOS Browsers
+

+ (default settings) +
+ + edge logo +
+ edge +
+ 123.2420 +
+
+
State Partitioning testsWhich browsers isolate websites to prevent them from sharing data to track you?
+
A common vulnerability of web browsers is that they allow tracking companies to 'tag' your browser with some data ('state') that identifies you. When third-party trackers are embedded in websites, they can see this identifying data as you browse to different websites. Fortunately, it is possible for this category of leaks to be fixed by partitioning all data stored in the browser such that no data can be shared between websites.
+        
+
Alt-Svc
+
Alt-Svc allows the server to indicate to the web browser that a resource should be loaded on a different server. Because this is a persistent setting, it could be used to track users across websites if it is not correctly partitioned.
+              
Unsupported +
write: async () => {
+      // Clear Alt-Svc caching first.
+      let responseText = "";
+      for (let i = 0; i < 3; ++i) {
+        await fetch(altSvcOrigin + "/clear");
+        await sleepMs(100);
+      }
+      responseText = await fetchText(altSvcOrigin + "/protocol");
+      console.log("after clear:", responseText);
+      // Store "h3" state in Alt-Svc cache
+      for (let i = 0; i < 3; ++i) {
+        await fetch(altSvcOrigin + "/set");
+        await sleepMs(100);
+      }
+      responseText = await fetchText(altSvcOrigin + "/protocol");
+      console.log("after set:", responseText);
+    }
+
+read: async () => {
+      const protocol = await fetchText(altSvcOrigin + "/protocol");
+      if ((new URL(location)).searchParams.get("thirdparty") === "same") {
+        if (protocol !== "h3") {
+          throw new Error("Unsupported");
+        }
+      }
+      return protocol;
+    }
+
+result, same first party: 
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported
+
+result, different first party: h3, h3, h3, h3, h3
+
+unsupported: true, true, true, true, true
+
+passed: undefined
+
+test failed: false, false, false, false, false
+ +
+
blob
+
A 'blob URL' is a local reference to some raw data. Trackers can use a blob URL to share data between websites.
+              
Passed +
write: (secret) => {
+      try {
+        let blobURL = URL.createObjectURL(new Blob([secret]));
+        fetch(`${baseURI}blob?mode=write&key=${secret}&blobUrl=${encodeURIComponent(blobURL)}`);
+      } catch (e) {
+        throw new Error("Unsupported");
+      }
+    }
+
+read: async (secret) => {
+      let response = await fetch(`${baseURI}blob?mode=read&key=${secret}`);
+      let result = await response.json();
+      let blobUrl = decodeURIComponent(result.blobUrl);
+      let blobResponse = await fetch(blobUrl);
+      return blobResponse.text();
+    }
+
+result, same first party: 
+Error: Load failed,
+Error: Load failed,
+Error: Load failed,
+Error: Load failed,
+Error: Load failed
+
+result, different first party: 
+Error: Load failed,
+Error: Load failed,
+Error: Load failed,
+Error: Load failed,
+Error: Load failed
+
+unsupported: false, false, false, false, false
+
+passed: undefined
+
+test failed: true, true, true, true, true
+
+
BroadcastChannel
+
A BroadcastChannel is designed to send messages between tabs. In some browsers it can be used for cross-site communication and tracking.
+              
Passed +
write: (secret) => {
+      try {
+        let bc = new BroadcastChannel("secrets");
+        bc.onmessage = (event) => {
+          if (event.data === "request") {
+            bc.postMessage(secret);
+          }
+        };
+      } catch (e) {
+        throw new Error("Unsupported");
+      }
+    }
+
+read: () =>
+      new Promise((resolve, reject) => {
+        let bc = new BroadcastChannel("secrets");
+        bc.onmessage = (event) => {
+          if (event.data !== "request") {
+            resolve(event.data);
+          }
+        };
+        bc.postMessage("request");
+        setTimeout(() => reject({message: "no BroadcastChannel message"}), 3000);
+      })
+
+result, same first party: 
+Error: no BroadcastChannel message,
+Error: no BroadcastChannel message,
+Error: no BroadcastChannel message,
+Error: no BroadcastChannel message,
+Error: no BroadcastChannel message
+
+result, different first party: 
+Error: no BroadcastChannel message,
+Error: no BroadcastChannel message,
+Error: no BroadcastChannel message,
+Error: no BroadcastChannel message,
+Error: no BroadcastChannel message
+
+unsupported: false, false, false, false, false
+
+passed: undefined
+
+test failed: true, true, true, true, true
+
+
CacheStorage
+
The Cache API is a content storage mechanism originally introduced to support ServiceWorkers. If the same Cache object is accessible to multiple websites, it can be abused to track users.
+              
Passed +
write: async (key) => {
+      try {
+        let cache = await caches.open("supercookies");
+        cache.addAll([`test.css?key=${key}`]);
+      } catch (e) {
+        throw new Error("Unsupported");
+      }
+    }
+
+read: async () => {
+      let cache = await caches.open("supercookies");
+      let cacheKeys = await cache.keys();
+      let url = cacheKeys[0].url;
+      return (new URL(url)).searchParams.get("key");
+    }
+
+result, same first party: 
+02f50774-fc60-4de1-8b21-868329d0182c,
+fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0,
+8e954de4-8067-47e9-a148-bd3b15d35eb2,
+1f874c53-f7eb-49f6-98d6-7b3b61b7de86,
+c26b7b92-9670-4a29-a0b8-8ce4a1277817
+
+result, different first party: 
+Error: undefined is not an object (evaluating 'cacheKeys[0].url'),
+Error: undefined is not an object (evaluating 'cacheKeys[0].url'),
+Error: undefined is not an object (evaluating 'cacheKeys[0].url'),
+Error: undefined is not an object (evaluating 'cacheKeys[0].url'),
+Error: undefined is not an object (evaluating 'cacheKeys[0].url')
+
+unsupported: false, false, false, false, false
+
+passed: true, true, true, true, true
+
+test failed: false, false, false, false, false
+
+
cookie (HTTP)
+
The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them.
+              
Passed +
write: async (secret) => {
+      // Request a page that will send an HTTPOnly 'set-cookie' response header with secret value.
+      await fetch(`${baseURI}cookie?secret=${secret}_http`);
+    }
+
+read: async () => {
+      // Test if we now send a requests with a 'cookie' header containing the secret.
+      let response = await fetch(`${baseURI}headers`);
+      let cookie = (await response.json())["cookie"];
+      return cookie ? cookie.match(/secret=([\w-]+)/)[1]: null;
+    }
+
+result, same first party: 
+02f50774-fc60-4de1-8b21-868329d0182c_http,
+fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0_http,
+8e954de4-8067-47e9-a148-bd3b15d35eb2_http,
+1f874c53-f7eb-49f6-98d6-7b3b61b7de86_http,
+c26b7b92-9670-4a29-a0b8-8ce4a1277817_http
+
+result, different first party: , , , , 
+
+unsupported: false, false, false, false, false
+
+passed: true, true, true, true, true
+
+test failed: false, false, false, false, false
+
+
cookie (JS)
+
The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them.
+              
Passed +
write: (secret) => {
+      document.cookie = `secret=${secret}_js; max-age=3600; SameSite=None; Secure`;
+    }
+
+read: () => document.cookie ? document.cookie.match(/secret=([\w-]+)/)[1] : null
+
+result, same first party: 
+02f50774-fc60-4de1-8b21-868329d0182c_js,
+fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0_js,
+8e954de4-8067-47e9-a148-bd3b15d35eb2_js,
+1f874c53-f7eb-49f6-98d6-7b3b61b7de86_js,
+c26b7b92-9670-4a29-a0b8-8ce4a1277817_js
+
+result, different first party: , , , , 
+
+unsupported: false, false, false, false, false
+
+passed: true, true, true, true, true
+
+test failed: false, false, false, false, false
+
+
CookieStore
+
The Cookie Store API is an alternative asynchronous API for managing cookies, supported by some browsers.
+              
Unsupported +
write: (data) => {
+      const msPerHour = 60 * 60 * 1000;
+      if (!window.cookieStore) {
+        throw new Error("Unsupported");
+      }
+      window.cookieStore.set({
+        name: "partition_test",
+        value: data,
+        expires: Date.now() + msPerHour,
+        sameSite: "none"
+      });
+    }
+
+read: async () => {
+      if (!window.cookieStore) {
+        throw new Error("Unsupported");
+      }
+      const cookie = await window.cookieStore.get("partition_test");
+      if (!cookie) {
+        return null;
+      }
+      return cookie.value;
+    }
+
+result, same first party: 
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported
+
+result, different first party: 
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported
+
+unsupported: true, true, true, true, true
+
+passed: undefined
+
+test failed: false, false, false, false, false
+
+
CSS cache
+
CSS stylesheets are cached, and if that cache is shared between websites, it can be used to track users across sites.
+              
Passed +
write: async (key) => {
+      const href = testURI("resource", "css", key);
+      const head = document.getElementsByTagName("head")[0];
+      head.innerHTML += `<link type="text/css" rel="stylesheet" href="${href}">`;
+      const testElement = document.querySelector("#css");
+      let fontFamily;
+      while (true) {
+        await sleepMs(100);
+        fontFamily = getComputedStyle(testElement).fontFamily;
+        if (fontFamily.startsWith("fake")) {
+          break;
+        }
+      }
+      console.log(fontFamily);
+      return key;
+    }
+
+read: async (key) => {
+      const href = testURI("resource", "css", key);
+      const head = document.getElementsByTagName("head")[0];
+      head.innerHTML += `<link type="text/css" rel="stylesheet" href="${href}">`;
+      const testElement = document.querySelector("#css");
+      let fontFamily;
+      while (true) {
+        await sleepMs(100);
+        fontFamily = getComputedStyle(testElement).fontFamily;
+        if (fontFamily.startsWith("fake")) {
+          break;
+        }
+      }
+      console.log(fontFamily);
+      return fontFamily;
+    }
+
+result, same first party: 
+fake_049793877173841095,
+fake_8205556862175178,
+fake_42952860144205474,
+fake_543893125893234,
+fake_5077793889816478
+
+result, different first party: 
+fake_6478738261288255,
+fake_04326589365858369,
+fake_8710860000208402,
+fake_112270928658317,
+fake_4468123948686622
+
+unsupported: false, false, false, false, false
+
+passed: true, true, true, true, true
+
+test failed: false, false, false, false, false
+
+
favicon cache
+
A favicon is an icon that represents a website, typically shown in browser tab and bookmarks menu. If the favicon cache is not partitioned, it can be used to track users across websites.
+              
Failed +
write: (key) => key
+
+read: async (key) => {
+      // Wait for the favicon to load (defined in supercookies.html)
+      await sleepMs(2000);
+      let response = await fetch(
+        testURI("ctr", "favicon", key), {"cache": "reload"});
+      let count = (await response.text()).trim();
+      if (count === "0") {
+        throw new Error("No requests received");
+      }
+      return count;
+    }
+
+result, same first party: 1, 1, 1, 1, 1
+
+result, different first party: 1, 1, 1, 1, 1
+
+unsupported: false, false, false, false, false
+
+passed: false, false, false, false, false
+
+test failed: false, false, false, false, false
+
+
fetch cache
+
When a resource is received via the Fetch API, it is frequently cached. That cache can potentially be abused for cross-site tracking.
+              
Passed +
write: async (key) => {
+      let response = await fetch(testURI("resource", "fetch", key),
+                                 {cache: "force-cache"});
+      return key;
+    }
+
+read: async (key) => {
+      let response = await fetch(testURI("resource", "fetch", key),
+                                 {cache: "force-cache"});
+      let countResponse = await fetch(testURI("ctr", "fetch", key),
+                                      {cache: "reload"});
+      return (await countResponse.text()).trim();
+    }
+
+result, same first party: 1, 1, 1, 1, 1
+
+result, different first party: 2, 2, 2, 2, 2
+
+unsupported: false, false, false, false, false
+
+passed: true, true, true, true, true
+
+test failed: false, false, false, false, false
+
+
font cache
+
Web fonts are sometimes stored in their own cache, which is vulnerable to being abused for cross-site tracking.
+              
Passed +
write: async (key) => {
+      let style = document.createElement("style");
+      style.type='text/css';
+      let fontURI = testURI("resource", "font", key);
+      style.innerHTML = `@font-face {font-family: "myFont"; src: url("${fontURI}"); } body { font-family: "myFont" }`;
+      document.getElementsByTagName("head")[0].appendChild(style);
+      return key;
+    }
+
+read: async (key) => {
+      const text = document.createElement("span");
+      text.id = "text";
+      text.innerText = "test";
+      document.body.appendChild(text);
+      const originalWidth = text.getBoundingClientRect().width;
+      let style = document.createElement("style");
+      style.type='text/css';
+      let fontURI = testURI("resource", "font", key);
+      style.innerHTML = `@font-face {font-family: "myFont"; src: url("${fontURI}"); } #text { font-family: "myFont" }`;
+      document.getElementsByTagName("head")[0].appendChild(style);
+      let newWidth;
+      do {
+        await sleepMs(100);
+        newWidth = text.getBoundingClientRect().width;
+      } while (newWidth < 0 || newWidth === originalWidth)
+      let response = await fetch(
+        testURI("ctr", "font", key), {"cache": "reload"});
+      return (await response.text()).trim();
+    }
+
+result, same first party: 2, 2, 2, 2, 2
+
+result, different first party: 3, 3, 3, 3, 3
+
+unsupported: false, false, false, false, false
+
+passed: true, true, true, true, true
+
+test failed: false, false, false, false, false
+
+
getDirectory
+
navigator.storage.getDirectory exposes a location for storing files to web content. In some cases, these files may be shared across tabs.
+              
Unsupported +
write: async (secret) => {
+      try {
+        const root = await navigator.storage.getDirectory();
+        const fileHandle = await root.getFileHandle("secret.txt", { create: true });
+        const stream = await fileHandle.createWritable();
+        await stream.write(secret);
+        await stream.close();
+      } catch (e) {
+        throw new Error("Unsupported");
+      }
+    }
+
+read: async () => {
+      try {
+        const root = await navigator.storage.getDirectory();
+        const fileHandle = await root.getFileHandle("secret.txt");
+        const file = await fileHandle.getFile();
+        return file.text();
+      } catch (e) {
+        throw new Error("Unsupported");
+      }
+    }
+
+result, same first party: , , , , 
+
+result, different first party: 
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported
+
+unsupported: true, true, true, true, true
+
+passed: undefined
+
+test failed: false, false, false, false, false
+
+
H1 connection
+
HTTP/1.x are the classic web connection protocols. If these connections are re-used across websites, they can be used to track users.
+              
Passed +
write: async (secret) => {
+      await fetch(`https://h1.privacytests2.org:8901/?mode=write&secret=${secret}`, {cache: "no-store"});
+    }
+
+read: async () => {
+      let response = await fetch(`https://h1.privacytests2.org:8901/?mode=read`, {cache: "no-store"});
+      return await response.text();
+    }
+
+result, same first party: 
+02f50774-fc60-4de1-8b21-868329d0182c,
+fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0,
+8e954de4-8067-47e9-a148-bd3b15d35eb2,
+1f874c53-f7eb-49f6-98d6-7b3b61b7de86,
+c26b7b92-9670-4a29-a0b8-8ce4a1277817
+
+result, different first party: , , , , 
+
+unsupported: false, false, false, false, false
+
+passed: true, true, true, true, true
+
+test failed: false, false, false, false, false
+
+
H2 connection
+
HTTP/2 is a web connection protocol introduced in 2015. Some browsers re-use HTTP/2 connections across websites and can thus be used to track users.
+              
Passed +
write: async (secret) => {
+      await fetch(`https://h2.privacytests2.org:8902/?mode=write&secret=${secret}`, {cache: "no-store"});
+    }
+
+read: async () => {
+      let response = await fetch(`https://h2.privacytests2.org:8902/?mode=read`, {cache: "no-store"});
+      return await response.text();
+    }
+
+result, same first party: 
+02f50774-fc60-4de1-8b21-868329d0182c,
+fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0,
+8e954de4-8067-47e9-a148-bd3b15d35eb2,
+1f874c53-f7eb-49f6-98d6-7b3b61b7de86,
+c26b7b92-9670-4a29-a0b8-8ce4a1277817
+
+result, different first party: , , , , 
+
+unsupported: false, false, false, false, false
+
+passed: true, true, true, true, true
+
+test failed: false, false, false, false, false
+
+
H3 connection
+
HTTP/3 is a new standard HTTP connection protocol, still in draft but widely supported by browsers. If it is not partitioned, it can be used to track users across websites.
+              
Passed +
write: async (secret) => {
+      // Ensure that we can switch over to h3 via alt-svc:
+      for (let i = 0; i<3; ++i) {
+        await fetch(`https://h3.privacytests2.org:4434/connection_id`, {cache: "no-store"});
+        await sleepMs(500);
+      }
+      // Are we now connecting over h3?
+      let response = await fetch(`https://h3.privacytests2.org:4434/connection_id`, {cache: "no-store"});
+      let text = await response.text();
+      // Empty response text indicates we are not connecting over h3:
+      if (text.trim() === "") {
+        throw new Error("Unsupported");
+      }
+    }
+
+read: async () => {
+      let response = await fetch(`https://h3.privacytests2.org:4434/connection_id`);
+      return await response.text();
+    }
+
+result, same first party: , 6d06131f76f6da15e1b870be174e5ea3, 339345f0df8eba0416ec8e1d14910f77, fdb1024e2ac8931e24fc980da7859424, 0b72f40b57d8b4bd4abf67abcf47b996
+
+result, different first party: , f0431e05edc6e81e6f4496205e89fb11, ab1667dcef8e86fadbb8c544de58edb8, db8fe63c1b5b9fb467fe68f2db2c419a, 7c88961be38141b8d6ca684383065e89
+
+unsupported: true, false, false, false, false
+
+passed: , true, true, true, true
+
+test failed: false, false, false, false, false
+
+
HSTS cache
+
The HTTP Strict-Transport-Security response header allows a website to signal that it should only be accessed via HTTPS. The browser remembers this directive in a database, but if this database is not partitioned, then it can be used to track users across websites."
+              
Passed +
write: set HSTS flag
+
+read: read HSTS flag
+
+result, same first party: not tested, not tested, not tested, not tested, not tested
+
+result, different first party: Used http, Used http, Used http, Used http, Used http
+
+unsupported: false, false, false, false, false
+
+passed: true, true, true, true, true
+
+test failed: false, false, false, false, false
+
+
HSTS cache (fetch)
+
The HTTP Strict-Transport-Security response header allows a website to signal that it should only be accessed via HTTPS. The browser remembers this directive in a database, but if this database is not partitioned, then it can be used to track users across websites."
+              
Passed +
write: set HSTS flag
+
+read: read HSTS flag
+
+result, same first party: not tested, not tested, not tested, not tested, not tested
+
+result, different first party: Used http, Used http, Used http, Used http, Used http
+
+unsupported: false, false, false, false, false
+
+passed: true, true, true, true, true
+
+test failed: false, false, false, false, false
+
+
iframe cache
+
An iframe is an element in a web page than allows websites to embed a second web page. Caching of this web page could be abused for cross-site tracking.
+              
Passed +
write: (key) => new Promise((resolve, reject) => {
+      let iframe = document.createElement("iframe");
+      document.body.appendChild(iframe);
+      iframe.addEventListener("load", () => resolve(key), {once: true});
+      iframe.src = testURI("resource", "page", key);
+    })
+
+read: async (key) => {
+      let iframe = document.createElement("iframe");
+      document.body.appendChild(iframe);
+      let iframeLoadPromise = new Promise((resolve, reject) => {
+        iframe.addEventListener("load", resolve, {once: true});
+      });
+      let address = testURI("resource", "page", key);
+      iframe.src = address;
+      await iframeLoadPromise;
+      let response = await fetch(
+        testURI("ctr", "page", key), {"cache": "reload"});
+      return (await response.text()).trim();
+    }
+
+result, same first party: 1, 1, 1, 1, 1
+
+result, different first party: 2, 2, 2, 2, 2
+
+unsupported: false, false, false, false, false
+
+passed: true, true, true, true, true
+
+test failed: false, false, false, false, false
+
+
image cache
+
Caching of images in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking.
+              
Passed +
write: (key) => new Promise((resolve, reject) => {
+      let img = document.createElement("img");
+      document.body.appendChild(img);
+      img.addEventListener("load", () => resolve(key), {once: true});
+      img.src = testURI("resource", "image", key);
+    })
+
+read: async (key) => {
+      let img = document.createElement("img");
+      document.body.appendChild(img);
+      let imgLoadPromise = new Promise((resolve, reject) => {
+        img.addEventListener("load", resolve, {once: true});
+      });
+      img.src = testURI("resource", "image", key);
+      await imgLoadPromise;
+      let response = await fetch(
+        testURI("ctr", "image", key), {"cache": "reload"});
+      return (await response.text()).trim();
+    }
+
+result, same first party: 2, 2, 2, 2, 2
+
+result, different first party: 3, 3, 3, 3, 3
+
+unsupported: false, false, false, false, false
+
+passed: true, true, true, true, true
+
+test failed: false, false, false, false, false
+
+
indexedDB
+
The IndexedDB API exposes a transactional database to web pages. That database can be used to track users across websites, unless it is partitioned.
+              
Passed +
write: async (secret) => {
+      try {
+        return await IdbKeyVal.set("secret", secret);
+      } catch (e) {
+        throw new Error("Unsupported");
+      }
+    }
+
+read: () => IdbKeyVal.get("secret")
+
+result, same first party: 
+02f50774-fc60-4de1-8b21-868329d0182c,
+fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0,
+8e954de4-8067-47e9-a148-bd3b15d35eb2,
+1f874c53-f7eb-49f6-98d6-7b3b61b7de86,
+c26b7b92-9670-4a29-a0b8-8ce4a1277817
+
+result, different first party: undefined
+
+unsupported: false, false, false, false, false
+
+passed: true, true, true, true, true
+
+test failed: false, false, false, false, false
+
+
localStorage
+
The localStorage API gives websites access to a key-value database that will remain available across visits. If the localStorage API is not partitioned or blocked, it can also be used to track users across websites.
+              
Passed +
write: (secret) => localStorage.setItem("secret", secret)
+
+read: () => localStorage.getItem("secret")
+
+result, same first party: 
+02f50774-fc60-4de1-8b21-868329d0182c,
+fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0,
+8e954de4-8067-47e9-a148-bd3b15d35eb2,
+1f874c53-f7eb-49f6-98d6-7b3b61b7de86,
+c26b7b92-9670-4a29-a0b8-8ce4a1277817
+
+result, different first party: , , , , 
+
+unsupported: false, false, false, false, false
+
+passed: true, true, true, true, true
+
+test failed: false, false, false, false, false
+
+
locks
+
navigator.locks (only supported in some browsers) allows scripts on multiple tabs to coordinate. If this API is not partitioned, it can be used for cross-site tracking.
+              
Passed +
write: async (key) => {
+      if (navigator.locks) {
+        navigator.locks.request(key, lock => new Promise((f,r) => {}));
+        let queryResult = await navigator.locks.query();
+        return queryResult.held[0].clientId;
+      } else {
+        throw new Error("Unsupported");
+      }
+    }
+
+read: async () => {
+      if (navigator.locks) {
+        let queryResult = await navigator.locks.query();
+        return queryResult.held[0].name;
+      }
+    }
+
+result, same first party: 
+Error: undefined is not an object (evaluating 'queryResult.held[0].name'),
+Error: undefined is not an object (evaluating 'queryResult.held[0].name'),
+Error: undefined is not an object (evaluating 'queryResult.held[0].name'),
+Error: undefined is not an object (evaluating 'queryResult.held[0].name'),
+Error: undefined is not an object (evaluating 'queryResult.held[0].name')
+
+result, different first party: 
+Error: undefined is not an object (evaluating 'queryResult.held[0].name'),
+Error: undefined is not an object (evaluating 'queryResult.held[0].name'),
+Error: undefined is not an object (evaluating 'queryResult.held[0].name'),
+Error: undefined is not an object (evaluating 'queryResult.held[0].name'),
+Error: undefined is not an object (evaluating 'queryResult.held[0].name')
+
+unsupported: false, false, false, false, false
+
+passed: undefined
+
+test failed: true, true, true, true, true
+
+
prefetch cache
+
A <link rel='prefetch'...> suggests to browsers they should fetch a resource ahead of time and cache it. But if browsers don't partition this cache, it can be used to track users across websites.
+              
Unsupported +
write: async (key) => {
+      let link = document.createElement("link");
+      link.rel = "prefetch";
+      link.href = testURI("resource", "prefetch", key);
+      document.getElementsByTagName("head")[0].appendChild(link);
+      return key;
+    }
+
+read: async (key) => {
+      let link = document.createElement("link");
+      link.rel = "prefetch";
+      link.href = testURI("resource", "prefetch", key);
+      document.getElementsByTagName("head")[0].appendChild(link);
+      await sleepMs(500);
+      let response = await fetch(
+        testURI("ctr", "prefetch", key), {"cache": "reload"});
+      let countString = (await response.text()).trim();
+      if (parseInt(countString) === 0) {
+        throw new Error("No requests received");
+      }
+      return countString;
+    }
+
+result, same first party: 
+Error: No requests received,
+Error: No requests received,
+Error: No requests received,
+Error: No requests received,
+Error: No requests received
+
+result, different first party: 
+Error: No requests received,
+Error: No requests received,
+Error: No requests received,
+Error: No requests received,
+Error: No requests received
+
+unsupported: true, true, true, true, true
+
+passed: undefined
+
+test failed: false, false, false, false, false
+
+
script cache
+
Caching of scripts in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking.
+              
Passed +
write: (key) => new Promise((resolve, reject) => {
+      let script = document.createElement("script");
+      document.body.appendChild(script);
+      script.addEventListener("load", () => resolve(key), {once: true});
+      script.src = testURI("resource", "script", key);
+    })
+
+read: async (key) => {
+      let script = document.createElement("script");
+      document.body.appendChild(script);
+      let scriptLoadPromise = new Promise((resolve, reject) => {
+        script.addEventListener("load", resolve, {once: true});
+      });
+      script.src = testURI("resource", "script", key);
+      await scriptLoadPromise;
+      let response = await fetch(
+        testURI("ctr", "script", key), {"cache": "reload"});
+      return (await response.text()).trim();
+    }
+
+result, same first party: 2, 2, 2, 2, 2
+
+result, different first party: 3, 3, 3, 3, 3
+
+unsupported: false, false, false, false, false
+
+passed: true, true, true, true, true
+
+test failed: false, false, false, false, false
+
+
ServiceWorker
+
The ServiceWorker API allows websites to run code in the background and store content in the browser for offline use. If a ServiceWorker can be accessed from multiple websites, it can be abused to track users across sites.
+              
Passed +
write: async (key) => {
+      if (!navigator.serviceWorker) {
+        throw new Error("Unsupported");
+      }
+      let registration = await navigator.serviceWorker.register(
+        'serviceWorker.js');
+      console.log(registration);
+      await navigator.serviceWorker.ready;
+      console.log("service worker ready");
+      await sleepMs(100);
+      await fetch(`serviceworker-write?secret=${key}`);
+    }
+
+read: async () => {
+      console.log("trying to register the serviceworker now...");
+      const registration = await Promise.race([
+        navigator.serviceWorker.register('serviceWorker.js'),
+        sleepMs(500)
+      ]);
+      if (registration === undefined) {
+        // We timed out or otherwise failed.
+        throw new Error("ServiceWorker registration failed");
+      }
+      console.log(registration);
+      await navigator.serviceWorker.ready;
+      console.log("service worker ready");
+      await sleepMs(100);
+      let response = await fetch("serviceworker-read");
+      return await response.text();
+    }
+
+result, same first party: , , , , 
+
+result, different first party: , , , , 
+
+unsupported: false, false, false, false, false
+
+passed: undefined
+
+test failed: true, true, true, true, true
+
+
SharedWorker
+
The SharedWorker API allows scripts from multiple tabs to share a background thread of computation. If SharedWorker is not partitioned, then it can be abused to shared data between websites in your browser.
+              
Unsupported +
write: async (secret) => {
+      try {
+        let worker = new SharedWorker("supercookies_sharedworker.js");
+        worker.port.start();
+//        console.log("worker", worker);
+        const messagePromise = new Promise((resolve) => {
+          worker.port.onmessage = (e) => resolve(e.data);
+        });
+        worker.port.postMessage(secret);
+        await messagePromise;
+      } catch (e) {
+        throw new Error("Unsupported");
+      }
+    }
+
+read: async () => {
+      let worker = new SharedWorker("supercookies_sharedworker.js");
+      worker.port.start();
+      const messagePromise = new Promise((resolve, reject) => {
+        worker.port.onmessage = (e) => resolve(e.data);
+        setTimeout(() => reject(new Error("no SharedWorker message received")), 200);
+      });
+      worker.port.postMessage("request");
+      const message = await messagePromise;
+      if (message === "none") {
+        throw new Error("Unsupported");
+      }
+      return message;
+    }
+
+result, same first party: 
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported
+
+result, different first party: 
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported
+
+unsupported: true, true, true, true, true
+
+passed: undefined
+
+test failed: false, false, false, false, false
+
+
TLS Session ID
+
The TLS protocol is used by HTTPS to make connections secure. If the browser were to re-use a TLS session, then the session ID could be used to track users across websites.
+              
Passed +
write: async () => {
+      let results = await fetch("https://tls.privacytests2.org:8900/");
+      return (await results.json()).sessionId;
+    }
+
+read: async () => {
+      let results = await fetch("https://tls.privacytests2.org:8900/");
+      return (await results.json()).sessionId;
+    }
+
+result, same first party: 
+ec82a0a66737a1b049a0b8e7d3d177d99f7d0fcc5af2b8e9b5880003077f6d09,
+bedc055b9b6bb7bdd21841eb317199ab2ab4354ff285eb13b5c8aa616d42d3b2,
+6f033d937b7df3f1487190a531bb16f9a0185428ecae760b87c6e8472db26659,
+e183413a2ad71761089da2ae17ad78e128c32fcd69544511f51b0ec5f5b0c5d5,
+ef239ed33733a079fad82acfd09c9ffc2303d0b66c68896eea047d1527d0085c
+
+result, different first party: 
+d7bfcfbfda8263ef91ca048d0d68228025ded6e6b5ca3cfee108f1956e9a3c7b,
+f8de1a5f6f0a1ead087583d3698c815793edb17f4fc94ed1127aee3877b6a866,
+079f6b80ad80403e7ba352dd0e0efaf599717efc4b28b335ab8b1ab892092640,
+f07d07776aed83766e51ca99dab00f472e8b5503ebddc3095310ca0ab167557e,
+2e41d8fd219b73b78f6a003b6f741f91a0d4b23d886760699c1853d3f8471e0c
+
+unsupported: false, false, false, false, false
+
+passed: true, true, true, true, true
+
+test failed: false, false, false, false, false
+
+
XMLHttpRequest cache
+
Similar to the newer Fetch API, any resource received may be cached by the browser. The cache is potentially vulnerable to cross-site tracking attack.
+              
Passed +
write: async (key) => {
+      const req = new XMLHttpRequest();
+      const loadPromise = new Promise(resolve => req.addEventListener("load", resolve));
+      req.open("GET", testURI("resource", "xhr", key));
+      req.send();
+      await loadPromise;
+      return key;
+    }
+
+read: async (key) => {
+      const req = new XMLHttpRequest();
+      const loadPromise = new Promise(resolve => req.addEventListener("load", resolve));
+      req.open("GET", testURI("resource", "xhr", key));
+      req.send();
+      await loadPromise;
+      let countResponse = await fetch(testURI("ctr", "xhr", key),
+                                      {cache: "reload"});
+      return (await countResponse.text()).trim();
+    }
+
+result, same first party: 1, 1, 1, 1, 1
+
+result, different first party: 2, 2, 2, 2, 2
+
+unsupported: false, false, false, false, false
+
+passed: true, true, true, true, true
+
+test failed: false, false, false, false, false
+
+
Navigation testsWhich browsers prevent websites from sharing tracking data when you click on a link?
+
When you click a hyperlink to navigate your browser from one site to another, certain browser APIs allow the first site to communicate to the second site. These privacy vulnerabilities can be fixed by introducing new limits on how much data is transfered between sites.',
+        
+
document.referrer
+
The Referer [sic] request header is a mechanism used by browsers to let a website know where the user is visiting from. This header is inherently tracking users across websites. In recent times, browsers have switched to a policy of trimming a referrer to convey less tracking information, but Referer continues to convey cross-site tracking data by default.
+              
Failed +
write: (secret) => { /* do nothing */ }
+
+read: () => document.referrer
+
+result, same first party: 
+https://test-pages.privacytests2.org/,
+https://test-pages.privacytests2.org/,
+https://test-pages.privacytests2.org/,
+https://test-pages.privacytests2.org/,
+https://test-pages.privacytests2.org/
+
+result, different first party: 
+https://test-pages.privacytests2.org/,
+https://test-pages.privacytests2.org/,
+https://test-pages.privacytests2.org/,
+https://test-pages.privacytests2.org/,
+https://test-pages.privacytests2.org/
+
+unsupported: false, false, false, false, false
+
+passed: false, false, false, false, false
+
+test failed: false, false, false, false, false
+ +
+
sessionStorage
+
The sessionStorage API is similar to the localStorage API, but it does not persist across tabs or across browser sessions. Nonetheless, it can be used to track users if they navigate from one website to another. This tracking can be thwarted by partitioning sessionStorage between websites.
+              
Passed +
write: (secret) => sessionStorage.setItem("secret", secret)
+
+read: () => sessionStorage.getItem("secret")
+
+result, same first party: 
+02f50774-fc60-4de1-8b21-868329d0182c,
+fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0,
+8e954de4-8067-47e9-a148-bd3b15d35eb2,
+1f874c53-f7eb-49f6-98d6-7b3b61b7de86,
+c26b7b92-9670-4a29-a0b8-8ce4a1277817
+
+result, different first party: , , , , 
+
+unsupported: false, false, false, false, false
+
+passed: true, true, true, true, true
+
+test failed: false, false, false, false, false
+
+
window.name
+
The window.name API allows websites to store data that will persist after the user has navigated the tab to a different website. This mechanism could be partitioned so that data is not allowed to persist between websites.
+              
Passed +
write: (secret) => window.name = "name_" + secret
+
+read: () => window.name
+
+result, same first party: 
+name_02f50774-fc60-4de1-8b21-868329d0182c,
+name_fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0,
+name_8e954de4-8067-47e9-a148-bd3b15d35eb2,
+name_1f874c53-f7eb-49f6-98d6-7b3b61b7de86,
+name_c26b7b92-9670-4a29-a0b8-8ce4a1277817
+
+result, different first party: , , , , 
+
+unsupported: false, false, false, false, false
+
+passed: true, true, true, true, true
+
+test failed: false, false, false, false, false
+
+
HTTPS testsWhich browsers prevent unencrypted network connections?
+
HTTPS is the protocol that web browsers use to connect securely to websites. When HTTPS is being used, the connection is encrypted so that third parties on the network cannot read content being sent between the server and your browser. In the past, insecure connections were the default and websites would need to actively request that a browser use HTTPS. Now the status quo is shifting, and browser makers are moving toward a world where HTTPS is the default protocol.`
+        
+
Insecure website warning
+
Checks to see if the browser stops loading an insecure website and warns the user before giving them the option to continue. Known as HTTPS-Only Mode in some browsers.
+              
Failed +
passed: false, false, false, false, false
+result: 
+Insecure website loaded,
+Insecure website loaded,
+Insecure website loaded,
+Insecure website loaded,
+Insecure website loaded
+ +
+
Upgradable address
+
Checks to see if an insecure address entered into the browser's address bar is upgraded to HTTPS whenever possible.
+              
Failed +
upgraded: false, false, false, false, false
+passed: false, false, false, false, false
+
+
Upgradable hyperlink
+
Checks to see if the user has clicked on a hyperlink to an insecure address, if the browser upgrades that address to HTTPS whenever possible.
+              
Failed +
upgraded: false, false, false, false, false
+passed: false, false, false, false, false
+
+
Upgradable image
+
Checks to see if the browser attempts to upgrade an insecure address for an image to HTTPS whenever possible.
+              
Passed +
passed: true, true, true, true, true
+result: upgraded, upgraded, upgraded, upgraded, upgraded
+
+
Upgradable script
+
Checks to see if the browser attempts to upgrade an insecure address for an script to HTTPS whenever possible.
+              
Passed +
passed: true, true, true, true, true
+result: blocked, blocked, blocked, blocked, blocked
+
+
Misc testsWhich browsers provide additional assorted privacy protections?
+
This category includes tests for the presence of miscellaneous privacy features
+        
+
ECH enabled
+
Encrypted Client Hello (ECH) is a new protocol that hides the website you are visiting from third-party network eavesdroppers.
+              
Failed +
SNI_status: plaintext
+passed: false, false, false, false, false
+ +
+
GPC enabled first-party
+
The Global Privacy Control is an HTTP header that can be sent by a browser to instruct a website not to sell the user's personal data to third parties. This test checks to see if the GPC header is sent by default to the top-level website.
+              
Failed +
header value: undefined
+passed: false, false, false, false, false
+
+
GPC enabled third-party
+
The Global Privacy Control is an HTTP header that can be sent by a browser to instruct a visited website not to sell the user's personal data to other parties. This test checks to see if the GPC header is sent to third-party elements on the web page.
+              
Failed +
passed: false, false, false, false, false
+
+
IP address leak
+
IP addresses can be used to uniquely identify a large percentage of users. A proxy, VPN, or Tor can mask a user's IP address.
+              
Failed +
passed: false, false, false, false, false
+
+
Stream isolation
+
Browsers that use Tor can use a different Tor circuit per top-level website.
+              
Unsupported +
write: () => {
+      if (!usingTor) {
+        throw new Error("Unsupported");
+      }
+    }
+read: async () => {
+      if (usingTor) {
+        return ipAddress;
+      } else {
+        throw new Error("Unsupported");
+      }
+    }
+unsupported: true, true, true, true, true
+readSameFirstParty: 
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported
+readDifferentFirstParty: 
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported
+testFailed: false, false, false, false, false
+
+
Tor enabled
+
The Tor network sends the browser's web requests through a series of relays to hide a user's IP address, thereby helping to mask their identity and location. This test checks to see if the Tor network is being used by default.
+              
Failed +
IsTorExit: false, false, false, false, false
+passed: false, false, false, false, false
+
+
Fingerprinting resistance testsWhich browsers hide what's unique about your device?
+
Fingerprinting is a technique trackers use to uniquely identify you as you browse the web. A fingerprinting script will measure several characteristics of your browser and, combining this data, will build a fingerprint that may uniquely identify you among web users. Browsers can introduce countermeasures, such as minimizing the distinguishing information disclosed by certain web APIs so your browser is harder to pick out from the crowd (so-called 'fingerprinting resistance').`,
+        
+
Media query screen height
+
Height of the user's screen in pixels.
+              
Failed +
expression: undefined
+desired expression: undefined
+actual value: 667,667,667,667,667
+desired value: undefined
+passed: false,false,false,false,false
+ +
+
Media query screen width
+
Width of the user's screen in pixels.
+              
Failed +
expression: undefined
+desired expression: undefined
+actual value: 375,375,375,375,375
+desired value: undefined
+passed: false,false,false,false,false
+
+
outerHeight
+
Height of the browser window in pixels, including browser chrome.
+              
Failed +
expression: outerHeight
+desired expression: undefined
+actual value: 561,561,561,561,561
+desired value: undefined
+passed: false,false,false,false,false
+
+
screen.height
+
Height of the user's screen, in pixels.
+              
Failed +
expression: screen.height
+desired expression: undefined
+actual value: 667,667,667,667,667
+desired value: undefined
+passed: false,false,false,false,false
+
+
screen.width
+
Width of the user's screen, in pixels.
+              
Failed +
expression: screen.width
+desired expression: undefined
+actual value: 375,375,375,375,375
+desired value: undefined
+passed: false,false,false,false,false
+
+
screenX
+
Position, in pixels, of the left edge of the browser window on screen.
+              
Passed +
expression: screenX
+desired expression: undefined
+actual value: 0,0,0,0,0
+desired value: undefined
+passed: true,true,true,true,true
+
+
screenY
+
Position, in pixels, of the top edge of the browser window on screen.
+              
Passed +
expression: screenY
+desired expression: undefined
+actual value: 0,0,0,0,0
+desired value: undefined
+passed: true,true,true,true,true
+
+
Tracking query parameter testsWhich browsers remove URL parameters that can track you?
+
When you browse from one web page to another, tracking companies will frequently attach a 'tracking query parameter' to the address of the second web page. That query parameter may contain a unique identifier that tracks you individually as you browse the web. And these query parameters are frequently synchronized with cookies, making them a powerful tracking vector. Web browsers can protect you from known tracking query parameters by stripping them from web addresses before your browser sends them. (The set of tracking query parameters tested here was largely borrowed from Brave.)`
+        
+
__hsfp
+
HubSpot tracking parameter
+              
Failed +
value: 534245130707274
+passed: false, false, false, false, false
+ +
+
__hssc
+
HubSpot tracking parameter
+              
Failed +
value: 534245130707274
+passed: false, false, false, false, false
+
+
__hstc
+
HubSpot tracking parameter
+              
Failed +
value: 534245130707274
+passed: false, false, false, false, false
+
+
__s
+
Drip.com email address tracking parameter
+              
Failed +
value: 534245130707274
+passed: false, false, false, false, false
+
+
_hsenc
+
HubSpot tracking parameter
+              
Failed +
value: 534245130707274
+passed: false, false, false, false, false
+
+
_openstat
+
Yandex tracking parameter
+              
Failed +
value: 534245130707274
+passed: false, false, false, false, false
+
+
dclid
+
DoubleClick Click ID (Google)
+              
Failed +
value: 534245130707274
+passed: false, false, false, false, false
+
+
fbclid
+
Facebook Click Identifier
+              
Failed +
value: 534245130707274
+passed: false, false, false, false, false
+
+
gclid
+
Google Click Identifier
+              
Failed +
value: 534245130707274
+passed: false, false, false, false, false
+
+
hsCtaTracking
+
HubSpot tracking parameter
+              
Failed +
value: 534245130707274
+passed: false, false, false, false, false
+
+
mc_eid
+
Mailchimp Email ID (email recipient's address)
+              
Failed +
value: 534245130707274
+passed: false, false, false, false, false
+
+
mkt_tok
+
Adobe Marketo tracking parameter
+              
Failed +
value: 534245130707274
+passed: false, false, false, false, false
+
+
ml_subscriber
+
MailerLite email tracking
+              
Failed +
value: 534245130707274
+passed: false, false, false, false, false
+
+
ml_subscriber_hash
+
MailerLite email tracking
+              
Failed +
value: 534245130707274
+passed: false, false, false, false, false
+
+
msclkid
+
Microsoft Click ID
+              
Failed +
value: 534245130707274
+passed: false, false, false, false, false
+
+
oly_anon_id
+
Omeda marketing 'anonymous' customer id
+              
Failed +
value: 534245130707274
+passed: false, false, false, false, false
+
+
oly_enc_id
+
Omeda marketing 'known' customer id
+              
Failed +
value: 534245130707274
+passed: false, false, false, false, false
+
+
rb_clickid
+
Unknown high-entropy tracking parameter
+              
Failed +
value: 534245130707274
+passed: false, false, false, false, false
+
+
s_cid
+
Adobe Site Catalyst tracking parameter
+              
Failed +
value: 534245130707274
+passed: false, false, false, false, false
+
+
vero_conv
+
Vero tracking parameter
+              
Failed +
value: 534245130707274
+passed: false, false, false, false, false
+
+
vero_id
+
Vero tracking parameter
+              
Failed +
value: 534245130707274
+passed: false, false, false, false, false
+
+
wickedid
+
Wicked Reports e-commerce tracking
+              
Failed +
value: 534245130707274
+passed: false, false, false, false, false
+
+
yclid
+
Yandex Click ID
+              
Failed +
value: 534245130707274
+passed: false, false, false, false, false
+
+
Tracker content blocking testsWhich browsers block important known tracking scripts and pixels?
+
When you visit a web page, it frequently has third-party embedded tracking content, such as scripts and tracking pixels. These embedded components spy on you. Some browsers and browser extensions maintain list of tracking companies and block their content from being loaded. This section checks to see if a browser blocks 20 of the largest trackers listed by https://whotracks.me.`
+        
+
Adobe
+
Tests whether the browser blocks the page from loading the tracker at https://munchkin.marketo.net/munchkin.js
+              
Failed +
url: https://munchkin.marketo.net/munchkin.js
+passed: false, false, false, false, false
+ +
+
Adobe Audience Manager
+
Tests whether the browser blocks the page from loading the tracker at https://dpm.demdex.net/ibs
+              
Failed +
url: https://dpm.demdex.net/ibs
+passed: false, false, false, false, false
+
+
Amazon adsystem
+
Tests whether the browser blocks the page from loading the tracker at https://s.amazon-adsystem.com/dcm
+              
Failed +
url: https://s.amazon-adsystem.com/dcm
+passed: false, false, false, false, false
+
+
AppNexus
+
Tests whether the browser blocks the page from loading the tracker at https://ib.adnxs.com/px?id=178248&t=1
+              
Failed +
url: https://ib.adnxs.com/px?id=178248&t=1
+passed: false, false, false, false, false
+
+
Bing Ads
+
Tests whether the browser blocks the page from loading the tracker at https://bat.bing.com/bat.js
+              
Failed +
url: https://bat.bing.com/bat.js
+passed: false, false, false, false, false
+
+
Chartbeat
+
Tests whether the browser blocks the page from loading the tracker at https://static.chartbeat.com/js/chartbeat.js
+              
Failed +
url: https://static.chartbeat.com/js/chartbeat.js
+passed: false, false, false, false, false
+
+
Criteo
+
Tests whether the browser blocks the page from loading the tracker at https://dis.criteo.com/dis/rtb/appnexus/cookiematch.aspx
+              
Failed +
url: https://dis.criteo.com/dis/rtb/appnexus/cookiematch.aspx
+passed: false, false, false, false, false
+
+
DoubleClick (Google)
+
Tests whether the browser blocks the page from loading the tracker at https://securepubads.g.doubleclick.net/static/glade.js
+              
Failed +
url: https://securepubads.g.doubleclick.net/static/glade.js
+passed: false, false, false, false, false
+
+
Facebook tracking
+
Tests whether the browser blocks the page from loading the tracker at https://connect.facebook.net/en_US/fbevents.js
+              
Failed +
url: https://connect.facebook.net/en_US/fbevents.js
+passed: false, false, false, false, false
+
+
Google (third-party ad pixel)
+
Tests whether the browser blocks the page from loading the tracker at https://www.google.com/pagead/1p-user-list/
+              
Failed +
url: https://www.google.com/pagead/1p-user-list/
+passed: false, false, false, false, false
+
+
Google Analytics
+
Tests whether the browser blocks the page from loading the tracker at https://google-analytics.com/urchin.js
+              
Failed +
url: https://google-analytics.com/urchin.js
+passed: false, false, false, false, false
+
+
Google Tag Manager
+
Tests whether the browser blocks the page from loading the tracker at https://www.googletagmanager.com/gtag.js?id=GTM-NX4SMZL
+              
Failed +
url: https://www.googletagmanager.com/gtag.js?id=GTM-NX4SMZL
+passed: false, false, false, false, false
+
+
Index Exchange
+
Tests whether the browser blocks the page from loading the tracker at https://dsum-sec.casalemedia.com/crum?cm_dsp_id=10&external_user_id=629685505537&C=1
+              
Failed +
url: https://dsum-sec.casalemedia.com/crum?cm_dsp_id=10&external_user_id=629685505537&C=1
+passed: false, false, false, false, false
+
+
New Relic
+
Tests whether the browser blocks the page from loading the tracker at https://js-agent.newrelic.com/nr-1212.min.js
+              
Failed +
url: https://js-agent.newrelic.com/nr-1212.min.js
+passed: false, false, false, false, false
+
+
Quantcast
+
Tests whether the browser blocks the page from loading the tracker at https://pixel.quantserve.com/pixel
+              
Failed +
url: https://pixel.quantserve.com/pixel
+passed: false, false, false, false, false
+
+
Scorecard Research Beacon
+
Tests whether the browser blocks the page from loading the tracker at https://sb.scorecardresearch.com/internal-c2/default/cs.js
+              
Failed +
url: https://sb.scorecardresearch.com/internal-c2/default/cs.js
+passed: false, false, false, false, false
+
+
Taboola
+
Tests whether the browser blocks the page from loading the tracker at https://trc.taboola.com/futureplc-tomsguide/trc/3/json
+              
Failed +
url: https://trc.taboola.com/futureplc-tomsguide/trc/3/json
+passed: false, false, false, false, false
+
+
Twitter pixel
+
Tests whether the browser blocks the page from loading the tracker at https://t.co/i/adsct
+              
Failed +
url: https://t.co/i/adsct
+passed: false, false, false, false, false
+
+
Yandex Ads
+
Tests whether the browser blocks the page from loading the tracker at https://yandex.ru/ads/system/header-bidding.js
+              
Failed +
url: https://yandex.ru/ads/system/header-bidding.js
+passed: false, false, false, false, false
+
+
Cross-session first-party tracking testsWhich browsers prevent websites from tracking you across browser sessions?
+
A common vulnerability of web browsers is that they allow websites ("first parties") to 'tag' your browser with some tracking data. This tag can be used to re-identify you when you return to a website you visited before. This category of leaks can be prevented by browser if they clean or isolate data between browser sessions. (In cases where a user has logged into a website or entered detailed information, it may be justifiable for a browser to retain information across sessions. These tests check when no such justification exists: when you have entered no significant information into a website, will the browser still retain data that allows you to be tracked across sessions?)
+        
+
Alt-Svc
+
Alt-Svc allows the server to indicate to the web browser that a resource should be loaded on a different server. Because this is a persistent setting, it could be used to track users across websites if it is not correctly partitioned.
+              
Passed +
write: async () => {
+      // Clear Alt-Svc caching first.
+      let responseText = "";
+      for (let i = 0; i < 3; ++i) {
+        await fetch(altSvcOrigin + "/clear");
+        await sleepMs(100);
+      }
+      responseText = await fetchText(altSvcOrigin + "/protocol");
+      console.log("after clear:", responseText);
+      // Store "h3" state in Alt-Svc cache
+      for (let i = 0; i < 3; ++i) {
+        await fetch(altSvcOrigin + "/set");
+        await sleepMs(100);
+      }
+      responseText = await fetchText(altSvcOrigin + "/protocol");
+      console.log("after set:", responseText);
+    }
+
+read: async () => {
+      const protocol = await fetchText(altSvcOrigin + "/protocol");
+      if ((new URL(location)).searchParams.get("thirdparty") === "same") {
+        if (protocol !== "h3") {
+          throw new Error("Unsupported");
+        }
+      }
+      return protocol;
+    }
+
+result, same session: h3, h2, h3, h2, h3
+
+result, different session: h2, h3, h2, h3, h2
+
+unsupported: false, true, false, true, false
+
+passed: true, true, true
+
+test failed: false, false, false, false, false
+ +
+
CacheStorage
+
The Cache API is a content storage mechanism originally introduced to support ServiceWorkers. If the same Cache object is accessible to multiple websites, it can be abused to track users.
+              
Failed +
write: async (key) => {
+      try {
+        let cache = await caches.open("supercookies");
+        cache.addAll([`test.css?key=${key}`]);
+      } catch (e) {
+        throw new Error("Unsupported");
+      }
+    }
+
+read: async () => {
+      let cache = await caches.open("supercookies");
+      let cacheKeys = await cache.keys();
+      let url = cacheKeys[0].url;
+      return (new URL(url)).searchParams.get("key");
+    }
+
+result, same session: 
+18747aa0-a493-4b2f-8684-a70dc7fadf6a_1p,
+18747aa0-a493-4b2f-8684-a70dc7fadf6a_1p,
+18747aa0-a493-4b2f-8684-a70dc7fadf6a_1p,
+18747aa0-a493-4b2f-8684-a70dc7fadf6a_1p,
+18747aa0-a493-4b2f-8684-a70dc7fadf6a_1p
+
+result, different session: 
+18747aa0-a493-4b2f-8684-a70dc7fadf6a_1p,
+18747aa0-a493-4b2f-8684-a70dc7fadf6a_1p,
+18747aa0-a493-4b2f-8684-a70dc7fadf6a_1p,
+18747aa0-a493-4b2f-8684-a70dc7fadf6a_1p,
+18747aa0-a493-4b2f-8684-a70dc7fadf6a_1p
+
+unsupported: false, false, false, false, false
+
+passed: false, false, false, false, false
+
+test failed: false, false, false, false, false
+
+
cookie (HTTP)
+
The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them.
+              
Failed +
write: async (secret) => {
+      // Request a page that will send an HTTPOnly 'set-cookie' response header with secret value.
+      await fetch(`${baseURI}cookie?secret=${secret}_http`);
+    }
+
+read: async () => {
+      // Test if we now send a requests with a 'cookie' header containing the secret.
+      let response = await fetch(`${baseURI}headers`);
+      let cookie = (await response.json())["cookie"];
+      return cookie ? cookie.match(/secret=([\w-]+)/)[1]: null;
+    }
+
+result, same session: 
+02f50774-fc60-4de1-8b21-868329d0182c_1p_http,
+fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0_1p_http,
+8e954de4-8067-47e9-a148-bd3b15d35eb2_1p_http,
+1f874c53-f7eb-49f6-98d6-7b3b61b7de86_1p_http,
+c26b7b92-9670-4a29-a0b8-8ce4a1277817_1p_http
+
+result, different session: 
+02f50774-fc60-4de1-8b21-868329d0182c_1p_http,
+fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0_1p_http,
+8e954de4-8067-47e9-a148-bd3b15d35eb2_1p_http,
+1f874c53-f7eb-49f6-98d6-7b3b61b7de86_1p_http,
+c26b7b92-9670-4a29-a0b8-8ce4a1277817_1p_http
+
+unsupported: false, false, false, false, false
+
+passed: false, false, false, false, false
+
+test failed: false, false, false, false, false
+
+
cookie (JS)
+
The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them.
+              
Failed +
write: (secret) => {
+      document.cookie = `secret=${secret}_js; max-age=3600; SameSite=None; Secure`;
+    }
+
+read: () => document.cookie ? document.cookie.match(/secret=([\w-]+)/)[1] : null
+
+result, same session: 
+02f50774-fc60-4de1-8b21-868329d0182c_1p_js,
+fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0_1p_js,
+8e954de4-8067-47e9-a148-bd3b15d35eb2_1p_js,
+1f874c53-f7eb-49f6-98d6-7b3b61b7de86_1p_js,
+c26b7b92-9670-4a29-a0b8-8ce4a1277817_1p_js
+
+result, different session: 
+02f50774-fc60-4de1-8b21-868329d0182c_1p_js,
+fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0_1p_js,
+8e954de4-8067-47e9-a148-bd3b15d35eb2_1p_js,
+1f874c53-f7eb-49f6-98d6-7b3b61b7de86_1p_js,
+c26b7b92-9670-4a29-a0b8-8ce4a1277817_1p_js
+
+unsupported: false, false, false, false, false
+
+passed: false, false, false, false, false
+
+test failed: false, false, false, false, false
+
+
CookieStore
+
The Cookie Store API is an alternative asynchronous API for managing cookies, supported by some browsers.
+              
Unsupported +
write: (data) => {
+      const msPerHour = 60 * 60 * 1000;
+      if (!window.cookieStore) {
+        throw new Error("Unsupported");
+      }
+      window.cookieStore.set({
+        name: "partition_test",
+        value: data,
+        expires: Date.now() + msPerHour,
+        sameSite: "none"
+      });
+    }
+
+read: async () => {
+      if (!window.cookieStore) {
+        throw new Error("Unsupported");
+      }
+      const cookie = await window.cookieStore.get("partition_test");
+      if (!cookie) {
+        return null;
+      }
+      return cookie.value;
+    }
+
+result, same session: 
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported
+
+result, different session: 
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported
+
+unsupported: true, true, true, true, true
+
+passed: undefined
+
+test failed: false, false, false, false, false
+
+
CSS cache
+
CSS stylesheets are cached, and if that cache is shared between websites, it can be used to track users across sites.
+              
Failed +
write: async (key) => {
+      const href = testURI("resource", "css", key);
+      const head = document.getElementsByTagName("head")[0];
+      head.innerHTML += `<link type="text/css" rel="stylesheet" href="${href}">`;
+      const testElement = document.querySelector("#css");
+      let fontFamily;
+      while (true) {
+        await sleepMs(100);
+        fontFamily = getComputedStyle(testElement).fontFamily;
+        if (fontFamily.startsWith("fake")) {
+          break;
+        }
+      }
+      console.log(fontFamily);
+      return key;
+    }
+
+read: async (key) => {
+      const href = testURI("resource", "css", key);
+      const head = document.getElementsByTagName("head")[0];
+      head.innerHTML += `<link type="text/css" rel="stylesheet" href="${href}">`;
+      const testElement = document.querySelector("#css");
+      let fontFamily;
+      while (true) {
+        await sleepMs(100);
+        fontFamily = getComputedStyle(testElement).fontFamily;
+        if (fontFamily.startsWith("fake")) {
+          break;
+        }
+      }
+      console.log(fontFamily);
+      return fontFamily;
+    }
+
+result, same session: 
+fake_48167822227964807,
+fake_41543632084179327,
+fake_17195563322684082,
+fake_9133452705961158,
+fake_2947887179279016
+
+result, different session: 
+fake_48167822227964807,
+fake_41543632084179327,
+fake_17195563322684082,
+fake_9133452705961158,
+fake_2947887179279016
+
+unsupported: false, false, false, false, false
+
+passed: false, false, false, false, false
+
+test failed: false, false, false, false, false
+
+
favicon cache
+
A favicon is an icon that represents a website, typically shown in browser tab and bookmarks menu. If the favicon cache is not partitioned, it can be used to track users across websites.
+              
Failed +
write: (key) => key
+
+read: async (key) => {
+      // Wait for the favicon to load (defined in supercookies.html)
+      await sleepMs(2000);
+      let response = await fetch(
+        testURI("ctr", "favicon", key), {"cache": "reload"});
+      let count = (await response.text()).trim();
+      if (count === "0") {
+        throw new Error("No requests received");
+      }
+      return count;
+    }
+
+result, same session: 1, 1, 1, 1, 1
+
+result, different session: 1, 1, 1, 1, 1
+
+unsupported: false, false, false, false, false
+
+passed: false, false, false, false, false
+
+test failed: false, false, false, false, false
+
+
fetch cache
+
When a resource is received via the Fetch API, it is frequently cached. That cache can potentially be abused for cross-site tracking.
+              
Failed +
write: async (key) => {
+      let response = await fetch(testURI("resource", "fetch", key),
+                                 {cache: "force-cache"});
+      return key;
+    }
+
+read: async (key) => {
+      let response = await fetch(testURI("resource", "fetch", key),
+                                 {cache: "force-cache"});
+      let countResponse = await fetch(testURI("ctr", "fetch", key),
+                                      {cache: "reload"});
+      return (await countResponse.text()).trim();
+    }
+
+result, same session: 1, 1, 1, 1, 1
+
+result, different session: 1, 1, 1, 1, 1
+
+unsupported: false, false, false, false, false
+
+passed: false, false, false, false, false
+
+test failed: false, false, false, false, false
+
+
font cache
+
Web fonts are sometimes stored in their own cache, which is vulnerable to being abused for cross-site tracking.
+              
Failed +
write: async (key) => {
+      let style = document.createElement("style");
+      style.type='text/css';
+      let fontURI = testURI("resource", "font", key);
+      style.innerHTML = `@font-face {font-family: "myFont"; src: url("${fontURI}"); } body { font-family: "myFont" }`;
+      document.getElementsByTagName("head")[0].appendChild(style);
+      return key;
+    }
+
+read: async (key) => {
+      const text = document.createElement("span");
+      text.id = "text";
+      text.innerText = "test";
+      document.body.appendChild(text);
+      const originalWidth = text.getBoundingClientRect().width;
+      let style = document.createElement("style");
+      style.type='text/css';
+      let fontURI = testURI("resource", "font", key);
+      style.innerHTML = `@font-face {font-family: "myFont"; src: url("${fontURI}"); } #text { font-family: "myFont" }`;
+      document.getElementsByTagName("head")[0].appendChild(style);
+      let newWidth;
+      do {
+        await sleepMs(100);
+        newWidth = text.getBoundingClientRect().width;
+      } while (newWidth < 0 || newWidth === originalWidth)
+      let response = await fetch(
+        testURI("ctr", "font", key), {"cache": "reload"});
+      return (await response.text()).trim();
+    }
+
+result, same session: 1, 1, 1, 1, 1
+
+result, different session: 1, 1, 1, 1, 1
+
+unsupported: false, false, false, false, false
+
+passed: false, false, false, false, false
+
+test failed: false, false, false, false, false
+
+
iframe cache
+
An iframe is an element in a web page than allows websites to embed a second web page. Caching of this web page could be abused for cross-site tracking.
+              
Failed +
write: (key) => new Promise((resolve, reject) => {
+      let iframe = document.createElement("iframe");
+      document.body.appendChild(iframe);
+      iframe.addEventListener("load", () => resolve(key), {once: true});
+      iframe.src = testURI("resource", "page", key);
+    })
+
+read: async (key) => {
+      let iframe = document.createElement("iframe");
+      document.body.appendChild(iframe);
+      let iframeLoadPromise = new Promise((resolve, reject) => {
+        iframe.addEventListener("load", resolve, {once: true});
+      });
+      let address = testURI("resource", "page", key);
+      iframe.src = address;
+      await iframeLoadPromise;
+      let response = await fetch(
+        testURI("ctr", "page", key), {"cache": "reload"});
+      return (await response.text()).trim();
+    }
+
+result, same session: 1, 1, 1, 1, 1
+
+result, different session: 1, 1, 1, 1, 1
+
+unsupported: false, false, false, false, false
+
+passed: false, false, false, false, false
+
+test failed: false, false, false, false, false
+
+
image cache
+
Caching of images in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking.
+              
Failed +
write: (key) => new Promise((resolve, reject) => {
+      let img = document.createElement("img");
+      document.body.appendChild(img);
+      img.addEventListener("load", () => resolve(key), {once: true});
+      img.src = testURI("resource", "image", key);
+    })
+
+read: async (key) => {
+      let img = document.createElement("img");
+      document.body.appendChild(img);
+      let imgLoadPromise = new Promise((resolve, reject) => {
+        img.addEventListener("load", resolve, {once: true});
+      });
+      img.src = testURI("resource", "image", key);
+      await imgLoadPromise;
+      let response = await fetch(
+        testURI("ctr", "image", key), {"cache": "reload"});
+      return (await response.text()).trim();
+    }
+
+result, same session: 1, 1, 1, 1, 1
+
+result, different session: 1, 1, 1, 1, 1
+
+unsupported: false, false, false, false, false
+
+passed: false, false, false, false, false
+
+test failed: false, false, false, false, false
+
+
indexedDB
+
The IndexedDB API exposes a transactional database to web pages. That database can be used to track users across websites, unless it is partitioned.
+              
Failed +
write: async (secret) => {
+      try {
+        return await IdbKeyVal.set("secret", secret);
+      } catch (e) {
+        throw new Error("Unsupported");
+      }
+    }
+
+read: () => IdbKeyVal.get("secret")
+
+result, same session: 
+02f50774-fc60-4de1-8b21-868329d0182c_1p,
+fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0_1p,
+8e954de4-8067-47e9-a148-bd3b15d35eb2_1p,
+1f874c53-f7eb-49f6-98d6-7b3b61b7de86_1p,
+c26b7b92-9670-4a29-a0b8-8ce4a1277817_1p
+
+result, different session: 
+02f50774-fc60-4de1-8b21-868329d0182c_1p,
+fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0_1p,
+8e954de4-8067-47e9-a148-bd3b15d35eb2_1p,
+1f874c53-f7eb-49f6-98d6-7b3b61b7de86_1p,
+c26b7b92-9670-4a29-a0b8-8ce4a1277817_1p
+
+unsupported: false, false, false, false, false
+
+passed: false, false, false, false, false
+
+test failed: false, false, false, false, false
+
+
localStorage
+
The localStorage API gives websites access to a key-value database that will remain available across visits. If the localStorage API is not partitioned or blocked, it can also be used to track users across websites.
+              
Failed +
write: (secret) => localStorage.setItem("secret", secret)
+
+read: () => localStorage.getItem("secret")
+
+result, same session: 
+02f50774-fc60-4de1-8b21-868329d0182c_1p,
+fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0_1p,
+8e954de4-8067-47e9-a148-bd3b15d35eb2_1p,
+1f874c53-f7eb-49f6-98d6-7b3b61b7de86_1p,
+c26b7b92-9670-4a29-a0b8-8ce4a1277817_1p
+
+result, different session: 
+02f50774-fc60-4de1-8b21-868329d0182c_1p,
+fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0_1p,
+8e954de4-8067-47e9-a148-bd3b15d35eb2_1p,
+1f874c53-f7eb-49f6-98d6-7b3b61b7de86_1p,
+c26b7b92-9670-4a29-a0b8-8ce4a1277817_1p
+
+unsupported: false, false, false, false, false
+
+passed: false, false, false, false, false
+
+test failed: false, false, false, false, false
+
+
prefetch cache
+
A <link rel='prefetch'...> suggests to browsers they should fetch a resource ahead of time and cache it. But if browsers don't partition this cache, it can be used to track users across websites.
+              
Unsupported +
write: async (key) => {
+      let link = document.createElement("link");
+      link.rel = "prefetch";
+      link.href = testURI("resource", "prefetch", key);
+      document.getElementsByTagName("head")[0].appendChild(link);
+      return key;
+    }
+
+read: async (key) => {
+      let link = document.createElement("link");
+      link.rel = "prefetch";
+      link.href = testURI("resource", "prefetch", key);
+      document.getElementsByTagName("head")[0].appendChild(link);
+      await sleepMs(500);
+      let response = await fetch(
+        testURI("ctr", "prefetch", key), {"cache": "reload"});
+      let countString = (await response.text()).trim();
+      if (parseInt(countString) === 0) {
+        throw new Error("No requests received");
+      }
+      return countString;
+    }
+
+result, same session: 
+Error: No requests received,
+Error: No requests received,
+Error: No requests received,
+Error: No requests received,
+Error: No requests received
+
+result, different session: 
+Error: No requests received,
+Error: No requests received,
+Error: No requests received,
+Error: No requests received,
+Error: No requests received
+
+unsupported: true, true, true, true, true
+
+passed: undefined
+
+test failed: false, false, false, false, false
+
+
script cache
+
Caching of scripts in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking.
+              
Failed +
write: (key) => new Promise((resolve, reject) => {
+      let script = document.createElement("script");
+      document.body.appendChild(script);
+      script.addEventListener("load", () => resolve(key), {once: true});
+      script.src = testURI("resource", "script", key);
+    })
+
+read: async (key) => {
+      let script = document.createElement("script");
+      document.body.appendChild(script);
+      let scriptLoadPromise = new Promise((resolve, reject) => {
+        script.addEventListener("load", resolve, {once: true});
+      });
+      script.src = testURI("resource", "script", key);
+      await scriptLoadPromise;
+      let response = await fetch(
+        testURI("ctr", "script", key), {"cache": "reload"});
+      return (await response.text()).trim();
+    }
+
+result, same session: 1, 1, 1, 1, 1
+
+result, different session: 1, 1, 1, 1, 1
+
+unsupported: false, false, false, false, false
+
+passed: false, false, false, false, false
+
+test failed: false, false, false, false, false
+
+
XMLHttpRequest cache
+
Similar to the newer Fetch API, any resource received may be cached by the browser. The cache is potentially vulnerable to cross-site tracking attack.
+              
Failed +
write: async (key) => {
+      const req = new XMLHttpRequest();
+      const loadPromise = new Promise(resolve => req.addEventListener("load", resolve));
+      req.open("GET", testURI("resource", "xhr", key));
+      req.send();
+      await loadPromise;
+      return key;
+    }
+
+read: async (key) => {
+      const req = new XMLHttpRequest();
+      const loadPromise = new Promise(resolve => req.addEventListener("load", resolve));
+      req.open("GET", testURI("resource", "xhr", key));
+      req.send();
+      await loadPromise;
+      let countResponse = await fetch(testURI("ctr", "xhr", key),
+                                      {cache: "reload"});
+      return (await countResponse.text()).trim();
+    }
+
+result, same session: 1, 1, 1, 1, 1
+
+result, different session: 1, 1, 1, 1, 1
+
+unsupported: false, false, false, false, false
+
+passed: false, false, false, false, false
+
+test failed: false, false, false, false, false
+
+
Cross-session third-party tracking testsWhich browsers prevent third-party trackers from tracking you across browser sessions?
+
A common vulnerability of web browsers is that they allow third-party trackers to 'tag' your browser with some tracking data. This tag can be used to re-identify you when you return to a website you visited before. This category of leaks can be prevented by browser if they clean or isolate data between browser sessions. (In cases where a user has logged into a website or entered detailed information, it may be justifiable for a browser to retain information across sessions. These tests check when no such justification exists: when you have entered no significant information into a website, will the browser still retain data that allows you to be tracked across sessions?)
+        
+
Alt-Svc
+
Alt-Svc allows the server to indicate to the web browser that a resource should be loaded on a different server. Because this is a persistent setting, it could be used to track users across websites if it is not correctly partitioned.
+              
Unsupported +
write: async () => {
+      // Clear Alt-Svc caching first.
+      let responseText = "";
+      for (let i = 0; i < 3; ++i) {
+        await fetch(altSvcOrigin + "/clear");
+        await sleepMs(100);
+      }
+      responseText = await fetchText(altSvcOrigin + "/protocol");
+      console.log("after clear:", responseText);
+      // Store "h3" state in Alt-Svc cache
+      for (let i = 0; i < 3; ++i) {
+        await fetch(altSvcOrigin + "/set");
+        await sleepMs(100);
+      }
+      responseText = await fetchText(altSvcOrigin + "/protocol");
+      console.log("after set:", responseText);
+    }
+
+read: async () => {
+      const protocol = await fetchText(altSvcOrigin + "/protocol");
+      if ((new URL(location)).searchParams.get("thirdparty") === "same") {
+        if (protocol !== "h3") {
+          throw new Error("Unsupported");
+        }
+      }
+      return protocol;
+    }
+
+result, same session: h2, h2, h2, h2, h2
+
+result, different session: h3, h3, h3, h3, h3
+
+unsupported: true, true, true, true, true
+
+passed: undefined
+
+test failed: false, false, false, false, false
+ +
+
CacheStorage
+
The Cache API is a content storage mechanism originally introduced to support ServiceWorkers. If the same Cache object is accessible to multiple websites, it can be abused to track users.
+              
Passed +
write: async (key) => {
+      try {
+        let cache = await caches.open("supercookies");
+        cache.addAll([`test.css?key=${key}`]);
+      } catch (e) {
+        throw new Error("Unsupported");
+      }
+    }
+
+read: async () => {
+      let cache = await caches.open("supercookies");
+      let cacheKeys = await cache.keys();
+      let url = cacheKeys[0].url;
+      return (new URL(url)).searchParams.get("key");
+    }
+
+result, same session: 
+7dac05a8-11cd-4c18-981d-3db1c7531ca6_3p,
+fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0_3p,
+8e954de4-8067-47e9-a148-bd3b15d35eb2_3p,
+1f874c53-f7eb-49f6-98d6-7b3b61b7de86_3p,
+c26b7b92-9670-4a29-a0b8-8ce4a1277817_3p
+
+result, different session: 
+Error: undefined is not an object (evaluating 'cacheKeys[0].url'),
+Error: undefined is not an object (evaluating 'cacheKeys[0].url'),
+Error: undefined is not an object (evaluating 'cacheKeys[0].url'),
+Error: undefined is not an object (evaluating 'cacheKeys[0].url'),
+Error: undefined is not an object (evaluating 'cacheKeys[0].url')
+
+unsupported: false, false, false, false, false
+
+passed: true, true, true, true, true
+
+test failed: false, false, false, false, false
+
+
cookie (HTTP)
+
The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them.
+              
Unsupported +
write: async (secret) => {
+      // Request a page that will send an HTTPOnly 'set-cookie' response header with secret value.
+      await fetch(`${baseURI}cookie?secret=${secret}_http`);
+    }
+
+read: async () => {
+      // Test if we now send a requests with a 'cookie' header containing the secret.
+      let response = await fetch(`${baseURI}headers`);
+      let cookie = (await response.json())["cookie"];
+      return cookie ? cookie.match(/secret=([\w-]+)/)[1]: null;
+    }
+
+result, same session: , , , , 
+
+result, different session: , , , , 
+
+unsupported: true, true, true, true, true
+
+passed: undefined
+
+test failed: false, false, false, false, false
+
+
cookie (JS)
+
The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them.
+              
Unsupported +
write: (secret) => {
+      document.cookie = `secret=${secret}_js; max-age=3600; SameSite=None; Secure`;
+    }
+
+read: () => document.cookie ? document.cookie.match(/secret=([\w-]+)/)[1] : null
+
+result, same session: , , , , 
+
+result, different session: , , , , 
+
+unsupported: true, true, true, true, true
+
+passed: undefined
+
+test failed: false, false, false, false, false
+
+
CookieStore
+
The Cookie Store API is an alternative asynchronous API for managing cookies, supported by some browsers.
+              
Unsupported +
write: (data) => {
+      const msPerHour = 60 * 60 * 1000;
+      if (!window.cookieStore) {
+        throw new Error("Unsupported");
+      }
+      window.cookieStore.set({
+        name: "partition_test",
+        value: data,
+        expires: Date.now() + msPerHour,
+        sameSite: "none"
+      });
+    }
+
+read: async () => {
+      if (!window.cookieStore) {
+        throw new Error("Unsupported");
+      }
+      const cookie = await window.cookieStore.get("partition_test");
+      if (!cookie) {
+        return null;
+      }
+      return cookie.value;
+    }
+
+result, same session: 
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported
+
+result, different session: 
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported,
+Error: Unsupported
+
+unsupported: true, true, true, true, true
+
+passed: undefined
+
+test failed: false, false, false, false, false
+
+
CSS cache
+
CSS stylesheets are cached, and if that cache is shared between websites, it can be used to track users across sites.
+              
Failed +
write: async (key) => {
+      const href = testURI("resource", "css", key);
+      const head = document.getElementsByTagName("head")[0];
+      head.innerHTML += `<link type="text/css" rel="stylesheet" href="${href}">`;
+      const testElement = document.querySelector("#css");
+      let fontFamily;
+      while (true) {
+        await sleepMs(100);
+        fontFamily = getComputedStyle(testElement).fontFamily;
+        if (fontFamily.startsWith("fake")) {
+          break;
+        }
+      }
+      console.log(fontFamily);
+      return key;
+    }
+
+read: async (key) => {
+      const href = testURI("resource", "css", key);
+      const head = document.getElementsByTagName("head")[0];
+      head.innerHTML += `<link type="text/css" rel="stylesheet" href="${href}">`;
+      const testElement = document.querySelector("#css");
+      let fontFamily;
+      while (true) {
+        await sleepMs(100);
+        fontFamily = getComputedStyle(testElement).fontFamily;
+        if (fontFamily.startsWith("fake")) {
+          break;
+        }
+      }
+      console.log(fontFamily);
+      return fontFamily;
+    }
+
+result, same session: 
+fake_6308298430769221,
+fake_7433174956497555,
+fake_2563349718763097,
+fake_27628504749770655,
+fake_6585637624788512
+
+result, different session: 
+fake_6308298430769221,
+fake_7433174956497555,
+fake_2563349718763097,
+fake_27628504749770655,
+fake_6585637624788512
+
+unsupported: false, false, false, false, false
+
+passed: false, false, false, false, false
+
+test failed: false, false, false, false, false
+
+
favicon cache
+
A favicon is an icon that represents a website, typically shown in browser tab and bookmarks menu. If the favicon cache is not partitioned, it can be used to track users across websites.
+              
Failed +
write: (key) => key
+
+read: async (key) => {
+      // Wait for the favicon to load (defined in supercookies.html)
+      await sleepMs(2000);
+      let response = await fetch(
+        testURI("ctr", "favicon", key), {"cache": "reload"});
+      let count = (await response.text()).trim();
+      if (count === "0") {
+        throw new Error("No requests received");
+      }
+      return count;
+    }
+
+result, same session: 1, 1, 1, 1, 1
+
+result, different session: 1, 1, 1, 1, 1
+
+unsupported: false, false, false, false, false
+
+passed: false, false, false, false, false
+
+test failed: false, false, false, false, false
+
+
fetch cache
+
When a resource is received via the Fetch API, it is frequently cached. That cache can potentially be abused for cross-site tracking.
+              
Failed +
write: async (key) => {
+      let response = await fetch(testURI("resource", "fetch", key),
+                                 {cache: "force-cache"});
+      return key;
+    }
+
+read: async (key) => {
+      let response = await fetch(testURI("resource", "fetch", key),
+                                 {cache: "force-cache"});
+      let countResponse = await fetch(testURI("ctr", "fetch", key),
+                                      {cache: "reload"});
+      return (await countResponse.text()).trim();
+    }
+
+result, same session: 1, 1, 1, 1, 1
+
+result, different session: 1, 1, 1, 1, 1
+
+unsupported: false, false, false, false, false
+
+passed: false, false, false, false, false
+
+test failed: false, false, false, false, false
+
+
font cache
+
Web fonts are sometimes stored in their own cache, which is vulnerable to being abused for cross-site tracking.
+              
Failed +
write: async (key) => {
+      let style = document.createElement("style");
+      style.type='text/css';
+      let fontURI = testURI("resource", "font", key);
+      style.innerHTML = `@font-face {font-family: "myFont"; src: url("${fontURI}"); } body { font-family: "myFont" }`;
+      document.getElementsByTagName("head")[0].appendChild(style);
+      return key;
+    }
+
+read: async (key) => {
+      const text = document.createElement("span");
+      text.id = "text";
+      text.innerText = "test";
+      document.body.appendChild(text);
+      const originalWidth = text.getBoundingClientRect().width;
+      let style = document.createElement("style");
+      style.type='text/css';
+      let fontURI = testURI("resource", "font", key);
+      style.innerHTML = `@font-face {font-family: "myFont"; src: url("${fontURI}"); } #text { font-family: "myFont" }`;
+      document.getElementsByTagName("head")[0].appendChild(style);
+      let newWidth;
+      do {
+        await sleepMs(100);
+        newWidth = text.getBoundingClientRect().width;
+      } while (newWidth < 0 || newWidth === originalWidth)
+      let response = await fetch(
+        testURI("ctr", "font", key), {"cache": "reload"});
+      return (await response.text()).trim();
+    }
+
+result, same session: 1, 1, 1, 1, 1
+
+result, different session: 1, 1, 1, 1, 1
+
+unsupported: false, false, false, false, false
+
+passed: false, false, false, false, false
+
+test failed: false, false, false, false, false
+
+
iframe cache
+
An iframe is an element in a web page than allows websites to embed a second web page. Caching of this web page could be abused for cross-site tracking.
+              
Failed +
write: (key) => new Promise((resolve, reject) => {
+      let iframe = document.createElement("iframe");
+      document.body.appendChild(iframe);
+      iframe.addEventListener("load", () => resolve(key), {once: true});
+      iframe.src = testURI("resource", "page", key);
+    })
+
+read: async (key) => {
+      let iframe = document.createElement("iframe");
+      document.body.appendChild(iframe);
+      let iframeLoadPromise = new Promise((resolve, reject) => {
+        iframe.addEventListener("load", resolve, {once: true});
+      });
+      let address = testURI("resource", "page", key);
+      iframe.src = address;
+      await iframeLoadPromise;
+      let response = await fetch(
+        testURI("ctr", "page", key), {"cache": "reload"});
+      return (await response.text()).trim();
+    }
+
+result, same session: 1, 1, 1, 1, 1
+
+result, different session: 1, 1, 1, 1, 1
+
+unsupported: false, false, false, false, false
+
+passed: false, false, false, false, false
+
+test failed: false, false, false, false, false
+
+
image cache
+
Caching of images in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking.
+              
Failed +
write: (key) => new Promise((resolve, reject) => {
+      let img = document.createElement("img");
+      document.body.appendChild(img);
+      img.addEventListener("load", () => resolve(key), {once: true});
+      img.src = testURI("resource", "image", key);
+    })
+
+read: async (key) => {
+      let img = document.createElement("img");
+      document.body.appendChild(img);
+      let imgLoadPromise = new Promise((resolve, reject) => {
+        img.addEventListener("load", resolve, {once: true});
+      });
+      img.src = testURI("resource", "image", key);
+      await imgLoadPromise;
+      let response = await fetch(
+        testURI("ctr", "image", key), {"cache": "reload"});
+      return (await response.text()).trim();
+    }
+
+result, same session: 1, 1, 1, 1, 1
+
+result, different session: 1, 1, 1, 1, 1
+
+unsupported: false, false, false, false, false
+
+passed: false, false, false, false, false
+
+test failed: false, false, false, false, false
+
+
indexedDB
+
The IndexedDB API exposes a transactional database to web pages. That database can be used to track users across websites, unless it is partitioned.
+              
Passed +
write: async (secret) => {
+      try {
+        return await IdbKeyVal.set("secret", secret);
+      } catch (e) {
+        throw new Error("Unsupported");
+      }
+    }
+
+read: () => IdbKeyVal.get("secret")
+
+result, same session: 
+02f50774-fc60-4de1-8b21-868329d0182c_3p,
+fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0_3p,
+8e954de4-8067-47e9-a148-bd3b15d35eb2_3p,
+1f874c53-f7eb-49f6-98d6-7b3b61b7de86_3p,
+c26b7b92-9670-4a29-a0b8-8ce4a1277817_3p
+
+result, different session: undefined
+
+unsupported: false, false, false, false, false
+
+passed: true, true, true, true, true
+
+test failed: false, false, false, false, false
+
+
localStorage
+
The localStorage API gives websites access to a key-value database that will remain available across visits. If the localStorage API is not partitioned or blocked, it can also be used to track users across websites.
+              
Passed +
write: (secret) => localStorage.setItem("secret", secret)
+
+read: () => localStorage.getItem("secret")
+
+result, same session: 
+02f50774-fc60-4de1-8b21-868329d0182c_3p,
+fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0_3p,
+8e954de4-8067-47e9-a148-bd3b15d35eb2_3p,
+1f874c53-f7eb-49f6-98d6-7b3b61b7de86_3p,
+c26b7b92-9670-4a29-a0b8-8ce4a1277817_3p
+
+result, different session: , , , , 
+
+unsupported: false, false, false, false, false
+
+passed: true, true, true, true, true
+
+test failed: false, false, false, false, false
+
+
prefetch cache
+
A <link rel='prefetch'...> suggests to browsers they should fetch a resource ahead of time and cache it. But if browsers don't partition this cache, it can be used to track users across websites.
+              
Unsupported +
write: async (key) => {
+      let link = document.createElement("link");
+      link.rel = "prefetch";
+      link.href = testURI("resource", "prefetch", key);
+      document.getElementsByTagName("head")[0].appendChild(link);
+      return key;
+    }
+
+read: async (key) => {
+      let link = document.createElement("link");
+      link.rel = "prefetch";
+      link.href = testURI("resource", "prefetch", key);
+      document.getElementsByTagName("head")[0].appendChild(link);
+      await sleepMs(500);
+      let response = await fetch(
+        testURI("ctr", "prefetch", key), {"cache": "reload"});
+      let countString = (await response.text()).trim();
+      if (parseInt(countString) === 0) {
+        throw new Error("No requests received");
+      }
+      return countString;
+    }
+
+result, same session: 
+Error: No requests received,
+Error: No requests received,
+Error: No requests received,
+Error: No requests received,
+Error: No requests received
+
+result, different session: 
+Error: No requests received,
+Error: No requests received,
+Error: No requests received,
+Error: No requests received,
+Error: No requests received
+
+unsupported: true, true, true, true, true
+
+passed: undefined
+
+test failed: false, false, false, false, false
+
+
script cache
+
Caching of scripts in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking.
+              
Failed +
write: (key) => new Promise((resolve, reject) => {
+      let script = document.createElement("script");
+      document.body.appendChild(script);
+      script.addEventListener("load", () => resolve(key), {once: true});
+      script.src = testURI("resource", "script", key);
+    })
+
+read: async (key) => {
+      let script = document.createElement("script");
+      document.body.appendChild(script);
+      let scriptLoadPromise = new Promise((resolve, reject) => {
+        script.addEventListener("load", resolve, {once: true});
+      });
+      script.src = testURI("resource", "script", key);
+      await scriptLoadPromise;
+      let response = await fetch(
+        testURI("ctr", "script", key), {"cache": "reload"});
+      return (await response.text()).trim();
+    }
+
+result, same session: 1, 1, 1, 1, 1
+
+result, different session: 1, 1, 1, 1, 1
+
+unsupported: false, false, false, false, false
+
+passed: false, false, false, false, false
+
+test failed: false, false, false, false, false
+
+
XMLHttpRequest cache
+
Similar to the newer Fetch API, any resource received may be cached by the browser. The cache is potentially vulnerable to cross-site tracking attack.
+              
Failed +
write: async (key) => {
+      const req = new XMLHttpRequest();
+      const loadPromise = new Promise(resolve => req.addEventListener("load", resolve));
+      req.open("GET", testURI("resource", "xhr", key));
+      req.send();
+      await loadPromise;
+      return key;
+    }
+
+read: async (key) => {
+      const req = new XMLHttpRequest();
+      const loadPromise = new Promise(resolve => req.addEventListener("load", resolve));
+      req.open("GET", testURI("resource", "xhr", key));
+      req.send();
+      await loadPromise;
+      let countResponse = await fetch(testURI("ctr", "xhr", key),
+                                      {cache: "reload"});
+      return (await countResponse.text()).trim();
+    }
+
+result, same session: 1, 1, 1, 1, 1
+
+result, different session: 1, 1, 1, 1, 1
+
+unsupported: false, false, false, false, false
+
+passed: false, false, false, false, false
+
+test failed: false, false, false, false, false
+
+ + +
+ + \ No newline at end of file diff --git a/archive/issue84/ios-edge.json b/archive/issue84/ios-edge.json new file mode 100644 index 00000000..5c39fdff --- /dev/null +++ b/archive/issue84/ios-edge.json @@ -0,0 +1 @@ +{"all_tests":[{"browser":"edge","incognito":false,"tor":false,"nightly":false,"testResults":{"session_3p":{"cookie (JS)":{"unsupported":true,"testFailed":false,"write":"(secret) => {\n document.cookie = `secret=${secret}_js; max-age=3600; SameSite=None; Secure`;\n }","read":"() => document.cookie ? document.cookie.match(/secret=([\\w-]+)/)[1] : null","description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them.","readSameSession":null,"readDifferentSession":null},"cookie (HTTP)":{"unsupported":true,"testFailed":false,"write":"async (secret) => {\n // Request a page that will send an HTTPOnly 'set-cookie' response header with secret value.\n await fetch(`${baseURI}cookie?secret=${secret}_http`);\n }","read":"async () => {\n // Test if we now send a requests with a 'cookie' header containing the secret.\n let response = await fetch(`${baseURI}headers`);\n let cookie = (await response.json())[\"cookie\"];\n return cookie ? cookie.match(/secret=([\\w-]+)/)[1]: null;\n }","description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them.","readSameSession":null,"readDifferentSession":null},"localStorage":{"unsupported":false,"passed":true,"testFailed":false,"write":"(secret) => localStorage.setItem(\"secret\", secret)","read":"() => localStorage.getItem(\"secret\")","description":"The localStorage API gives websites access to a key-value database that will remain available across visits. If the localStorage API is not partitioned or blocked, it can also be used to track users across websites.","readSameSession":"02f50774-fc60-4de1-8b21-868329d0182c_3p","readDifferentSession":null},"indexedDB":{"unsupported":false,"passed":true,"testFailed":false,"write":"async (secret) => {\n try {\n return await IdbKeyVal.set(\"secret\", secret);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"() => IdbKeyVal.get(\"secret\")","description":"The IndexedDB API exposes a transactional database to web pages. That database can be used to track users across websites, unless it is partitioned.","readSameSession":"02f50774-fc60-4de1-8b21-868329d0182c_3p"},"fetch cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n return key;\n }","read":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n let countResponse = await fetch(testURI(\"ctr\", \"fetch\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","description":"When a resource is received via the Fetch API, it is frequently cached. That cache can potentially be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"XMLHttpRequest cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n return key;\n }","read":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n let countResponse = await fetch(testURI(\"ctr\", \"xhr\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","description":"Similar to the newer Fetch API, any resource received may be cached by the browser. The cache is potentially vulnerable to cross-site tracking attack.","readSameSession":"1","readDifferentSession":"1"},"iframe cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n iframe.addEventListener(\"load\", () => resolve(key), {once: true});\n iframe.src = testURI(\"resource\", \"page\", key);\n })","read":"async (key) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n let iframeLoadPromise = new Promise((resolve, reject) => {\n iframe.addEventListener(\"load\", resolve, {once: true});\n });\n let address = testURI(\"resource\", \"page\", key);\n iframe.src = address;\n await iframeLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"page\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"An iframe is an element in a web page than allows websites to embed a second web page. Caching of this web page could be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"CacheStorage":{"unsupported":false,"passed":true,"testFailed":false,"write":"async (key) => {\n try {\n let cache = await caches.open(\"supercookies\");\n cache.addAll([`test.css?key=${key}`]);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n let cache = await caches.open(\"supercookies\");\n let cacheKeys = await cache.keys();\n let url = cacheKeys[0].url;\n return (new URL(url)).searchParams.get(\"key\");\n }","description":"The Cache API is a content storage mechanism originally introduced to support ServiceWorkers. If the same Cache object is accessible to multiple websites, it can be abused to track users.","readSameSession":"7dac05a8-11cd-4c18-981d-3db1c7531ca6_3p","readDifferentSession":"Error: undefined is not an object (evaluating 'cacheKeys[0].url')"},"favicon cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => key","read":"async (key) => {\n // Wait for the favicon to load (defined in supercookies.html)\n await sleepMs(2000);\n let response = await fetch(\n testURI(\"ctr\", \"favicon\", key), {\"cache\": \"reload\"});\n let count = (await response.text()).trim();\n if (count === \"0\") {\n throw new Error(\"No requests received\");\n }\n return count;\n }","description":"A favicon is an icon that represents a website, typically shown in browser tab and bookmarks menu. If the favicon cache is not partitioned, it can be used to track users across websites.","readSameSession":"1","readDifferentSession":"1"},"CookieStore":{"unsupported":true,"testFailed":false,"write":"(data) => {\n const msPerHour = 60 * 60 * 1000;\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n window.cookieStore.set({\n name: \"partition_test\",\n value: data,\n expires: Date.now() + msPerHour,\n sameSite: \"none\"\n });\n }","read":"async () => {\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n const cookie = await window.cookieStore.get(\"partition_test\");\n if (!cookie) {\n return null;\n }\n return cookie.value;\n }","description":"The Cookie Store API is an alternative asynchronous API for managing cookies, supported by some browsers.","readSameSession":"Error: Unsupported","readDifferentSession":"Error: Unsupported"},"CSS cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return key;\n }","read":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return fontFamily;\n }","description":"CSS stylesheets are cached, and if that cache is shared between websites, it can be used to track users across sites.","readSameSession":"fake_6308298430769221","readDifferentSession":"fake_6308298430769221"},"image cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n img.addEventListener(\"load\", () => resolve(key), {once: true});\n img.src = testURI(\"resource\", \"image\", key);\n })","read":"async (key) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n let imgLoadPromise = new Promise((resolve, reject) => {\n img.addEventListener(\"load\", resolve, {once: true});\n });\n img.src = testURI(\"resource\", \"image\", key);\n await imgLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"image\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Caching of images in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"script cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n script.addEventListener(\"load\", () => resolve(key), {once: true});\n script.src = testURI(\"resource\", \"script\", key);\n })","read":"async (key) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n let scriptLoadPromise = new Promise((resolve, reject) => {\n script.addEventListener(\"load\", resolve, {once: true});\n });\n script.src = testURI(\"resource\", \"script\", key);\n await scriptLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"script\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Caching of scripts in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"font cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } body { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n return key;\n }","read":"async (key) => {\n const text = document.createElement(\"span\");\n text.id = \"text\";\n text.innerText = \"test\";\n document.body.appendChild(text);\n const originalWidth = text.getBoundingClientRect().width;\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } #text { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n let newWidth;\n do {\n await sleepMs(100);\n newWidth = text.getBoundingClientRect().width;\n } while (newWidth < 0 || newWidth === originalWidth)\n let response = await fetch(\n testURI(\"ctr\", \"font\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Web fonts are sometimes stored in their own cache, which is vulnerable to being abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"prefetch cache":{"unsupported":true,"testFailed":false,"write":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n return key;\n }","read":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n await sleepMs(500);\n let response = await fetch(\n testURI(\"ctr\", \"prefetch\", key), {\"cache\": \"reload\"});\n let countString = (await response.text()).trim();\n if (parseInt(countString) === 0) {\n throw new Error(\"No requests received\");\n }\n return countString;\n }","description":"A suggests to browsers they should fetch a resource ahead of time and cache it. But if browsers don't partition this cache, it can be used to track users across websites.","readSameSession":"Error: No requests received","readDifferentSession":"Error: No requests received"},"Alt-Svc":{"unsupported":true,"testFailed":false,"write":"async () => {\n // Clear Alt-Svc caching first.\n let responseText = \"\";\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/clear\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after clear:\", responseText);\n // Store \"h3\" state in Alt-Svc cache\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/set\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after set:\", responseText);\n }","read":"async () => {\n const protocol = await fetchText(altSvcOrigin + \"/protocol\");\n if ((new URL(location)).searchParams.get(\"thirdparty\") === \"same\") {\n if (protocol !== \"h3\") {\n throw new Error(\"Unsupported\");\n }\n }\n return protocol;\n }","description":"Alt-Svc allows the server to indicate to the web browser that a resource should be loaded on a different server. Because this is a persistent setting, it could be used to track users across websites if it is not correctly partitioned.","readSameSession":"h2","readDifferentSession":"h3"}},"session_1p":{"cookie (JS)":{"unsupported":false,"passed":false,"testFailed":false,"write":"(secret) => {\n document.cookie = `secret=${secret}_js; max-age=3600; SameSite=None; Secure`;\n }","read":"() => document.cookie ? document.cookie.match(/secret=([\\w-]+)/)[1] : null","description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them.","readSameSession":"02f50774-fc60-4de1-8b21-868329d0182c_1p_js","readDifferentSession":"02f50774-fc60-4de1-8b21-868329d0182c_1p_js"},"cookie (HTTP)":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (secret) => {\n // Request a page that will send an HTTPOnly 'set-cookie' response header with secret value.\n await fetch(`${baseURI}cookie?secret=${secret}_http`);\n }","read":"async () => {\n // Test if we now send a requests with a 'cookie' header containing the secret.\n let response = await fetch(`${baseURI}headers`);\n let cookie = (await response.json())[\"cookie\"];\n return cookie ? cookie.match(/secret=([\\w-]+)/)[1]: null;\n }","description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them.","readSameSession":"02f50774-fc60-4de1-8b21-868329d0182c_1p_http","readDifferentSession":"02f50774-fc60-4de1-8b21-868329d0182c_1p_http"},"localStorage":{"unsupported":false,"passed":false,"testFailed":false,"write":"(secret) => localStorage.setItem(\"secret\", secret)","read":"() => localStorage.getItem(\"secret\")","description":"The localStorage API gives websites access to a key-value database that will remain available across visits. If the localStorage API is not partitioned or blocked, it can also be used to track users across websites.","readSameSession":"02f50774-fc60-4de1-8b21-868329d0182c_1p","readDifferentSession":"02f50774-fc60-4de1-8b21-868329d0182c_1p"},"indexedDB":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (secret) => {\n try {\n return await IdbKeyVal.set(\"secret\", secret);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"() => IdbKeyVal.get(\"secret\")","description":"The IndexedDB API exposes a transactional database to web pages. That database can be used to track users across websites, unless it is partitioned.","readSameSession":"02f50774-fc60-4de1-8b21-868329d0182c_1p","readDifferentSession":"02f50774-fc60-4de1-8b21-868329d0182c_1p"},"fetch cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n return key;\n }","read":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n let countResponse = await fetch(testURI(\"ctr\", \"fetch\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","description":"When a resource is received via the Fetch API, it is frequently cached. That cache can potentially be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"XMLHttpRequest cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n return key;\n }","read":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n let countResponse = await fetch(testURI(\"ctr\", \"xhr\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","description":"Similar to the newer Fetch API, any resource received may be cached by the browser. The cache is potentially vulnerable to cross-site tracking attack.","readSameSession":"1","readDifferentSession":"1"},"iframe cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n iframe.addEventListener(\"load\", () => resolve(key), {once: true});\n iframe.src = testURI(\"resource\", \"page\", key);\n })","read":"async (key) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n let iframeLoadPromise = new Promise((resolve, reject) => {\n iframe.addEventListener(\"load\", resolve, {once: true});\n });\n let address = testURI(\"resource\", \"page\", key);\n iframe.src = address;\n await iframeLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"page\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"An iframe is an element in a web page than allows websites to embed a second web page. Caching of this web page could be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"CacheStorage":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n try {\n let cache = await caches.open(\"supercookies\");\n cache.addAll([`test.css?key=${key}`]);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n let cache = await caches.open(\"supercookies\");\n let cacheKeys = await cache.keys();\n let url = cacheKeys[0].url;\n return (new URL(url)).searchParams.get(\"key\");\n }","description":"The Cache API is a content storage mechanism originally introduced to support ServiceWorkers. If the same Cache object is accessible to multiple websites, it can be abused to track users.","readSameSession":"18747aa0-a493-4b2f-8684-a70dc7fadf6a_1p","readDifferentSession":"18747aa0-a493-4b2f-8684-a70dc7fadf6a_1p"},"favicon cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => key","read":"async (key) => {\n // Wait for the favicon to load (defined in supercookies.html)\n await sleepMs(2000);\n let response = await fetch(\n testURI(\"ctr\", \"favicon\", key), {\"cache\": \"reload\"});\n let count = (await response.text()).trim();\n if (count === \"0\") {\n throw new Error(\"No requests received\");\n }\n return count;\n }","description":"A favicon is an icon that represents a website, typically shown in browser tab and bookmarks menu. If the favicon cache is not partitioned, it can be used to track users across websites.","readSameSession":"1","readDifferentSession":"1"},"CookieStore":{"unsupported":true,"testFailed":false,"write":"(data) => {\n const msPerHour = 60 * 60 * 1000;\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n window.cookieStore.set({\n name: \"partition_test\",\n value: data,\n expires: Date.now() + msPerHour,\n sameSite: \"none\"\n });\n }","read":"async () => {\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n const cookie = await window.cookieStore.get(\"partition_test\");\n if (!cookie) {\n return null;\n }\n return cookie.value;\n }","description":"The Cookie Store API is an alternative asynchronous API for managing cookies, supported by some browsers.","readSameSession":"Error: Unsupported","readDifferentSession":"Error: Unsupported"},"CSS cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return key;\n }","read":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return fontFamily;\n }","description":"CSS stylesheets are cached, and if that cache is shared between websites, it can be used to track users across sites.","readSameSession":"fake_48167822227964807","readDifferentSession":"fake_48167822227964807"},"image cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n img.addEventListener(\"load\", () => resolve(key), {once: true});\n img.src = testURI(\"resource\", \"image\", key);\n })","read":"async (key) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n let imgLoadPromise = new Promise((resolve, reject) => {\n img.addEventListener(\"load\", resolve, {once: true});\n });\n img.src = testURI(\"resource\", \"image\", key);\n await imgLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"image\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Caching of images in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"script cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n script.addEventListener(\"load\", () => resolve(key), {once: true});\n script.src = testURI(\"resource\", \"script\", key);\n })","read":"async (key) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n let scriptLoadPromise = new Promise((resolve, reject) => {\n script.addEventListener(\"load\", resolve, {once: true});\n });\n script.src = testURI(\"resource\", \"script\", key);\n await scriptLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"script\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Caching of scripts in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"font cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } body { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n return key;\n }","read":"async (key) => {\n const text = document.createElement(\"span\");\n text.id = \"text\";\n text.innerText = \"test\";\n document.body.appendChild(text);\n const originalWidth = text.getBoundingClientRect().width;\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } #text { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n let newWidth;\n do {\n await sleepMs(100);\n newWidth = text.getBoundingClientRect().width;\n } while (newWidth < 0 || newWidth === originalWidth)\n let response = await fetch(\n testURI(\"ctr\", \"font\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Web fonts are sometimes stored in their own cache, which is vulnerable to being abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"prefetch cache":{"unsupported":true,"testFailed":false,"write":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n return key;\n }","read":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n await sleepMs(500);\n let response = await fetch(\n testURI(\"ctr\", \"prefetch\", key), {\"cache\": \"reload\"});\n let countString = (await response.text()).trim();\n if (parseInt(countString) === 0) {\n throw new Error(\"No requests received\");\n }\n return countString;\n }","description":"A suggests to browsers they should fetch a resource ahead of time and cache it. But if browsers don't partition this cache, it can be used to track users across websites.","readSameSession":"Error: No requests received","readDifferentSession":"Error: No requests received"},"Alt-Svc":{"unsupported":false,"passed":true,"testFailed":false,"write":"async () => {\n // Clear Alt-Svc caching first.\n let responseText = \"\";\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/clear\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after clear:\", responseText);\n // Store \"h3\" state in Alt-Svc cache\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/set\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after set:\", responseText);\n }","read":"async () => {\n const protocol = await fetchText(altSvcOrigin + \"/protocol\");\n if ((new URL(location)).searchParams.get(\"thirdparty\") === \"same\") {\n if (protocol !== \"h3\") {\n throw new Error(\"Unsupported\");\n }\n }\n return protocol;\n }","description":"Alt-Svc allows the server to indicate to the web browser that a resource should be loaded on a different server. Because this is a persistent setting, it could be used to track users across websites if it is not correctly partitioned.","readSameSession":"h3","readDifferentSession":"h2"}},"misc":{"Tor enabled":{"IsTorExit":false,"passed":false,"description":"The Tor network sends the browser's web requests through a series of relays to hide a user's IP address, thereby helping to mask their identity and location. This test checks to see if the Tor network is being used by default."},"GPC enabled third-party":{"passed":false,"description":"The Global Privacy Control is an HTTP header that can be sent by a browser to instruct a visited website not to sell the user's personal data to other parties. This test checks to see if the GPC header is sent to third-party elements on the web page."},"ECH enabled":{"SNI_status":"plaintext","passed":false,"description":"Encrypted Client Hello (ECH) is a new protocol that hides the website you are visiting from third-party network eavesdroppers."},"Stream isolation":{"write":"() => {\n if (!usingTor) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n if (usingTor) {\n return ipAddress;\n } else {\n throw new Error(\"Unsupported\");\n }\n }","unsupported":true,"readSameFirstParty":"Error: Unsupported","readDifferentFirstParty":"Error: Unsupported","testFailed":false,"description":"Browsers that use Tor can use a different Tor circuit per top-level website."},"IP address leak":{"description":"IP addresses can be used to uniquely identify a large percentage of users. A proxy, VPN, or Tor can mask a user's IP address.","passed":false},"GPC enabled first-party":{"header value":"undefined","description":"The Global Privacy Control is an HTTP header that can be sent by a browser to instruct a website not to sell the user's personal data to third parties. This test checks to see if the GPC header is sent by default to the top-level website.","passed":false}},"query":{"fbclid":{"value":"534245130707274","passed":false,"description":"Facebook Click Identifier"},"gclid":{"value":"534245130707274","passed":false,"description":"Google Click Identifier"},"msclkid":{"value":"534245130707274","passed":false,"description":"Microsoft Click ID"},"mc_eid":{"value":"534245130707274","passed":false,"description":"Mailchimp Email ID (email recipient's address)"},"dclid":{"value":"534245130707274","passed":false,"description":"DoubleClick Click ID (Google)"},"oly_anon_id":{"value":"534245130707274","passed":false,"description":"Omeda marketing 'anonymous' customer id"},"oly_enc_id":{"value":"534245130707274","passed":false,"description":"Omeda marketing 'known' customer id"},"_openstat":{"value":"534245130707274","passed":false,"description":"Yandex tracking parameter"},"vero_conv":{"value":"534245130707274","passed":false,"description":"Vero tracking parameter"},"vero_id":{"value":"534245130707274","passed":false,"description":"Vero tracking parameter"},"wickedid":{"value":"534245130707274","passed":false,"description":"Wicked Reports e-commerce tracking"},"yclid":{"value":"534245130707274","passed":false,"description":"Yandex Click ID"},"__s":{"value":"534245130707274","passed":false,"description":"Drip.com email address tracking parameter"},"rb_clickid":{"value":"534245130707274","passed":false,"description":"Unknown high-entropy tracking parameter"},"s_cid":{"value":"534245130707274","passed":false,"description":"Adobe Site Catalyst tracking parameter"},"ml_subscriber":{"value":"534245130707274","passed":false,"description":"MailerLite email tracking"},"ml_subscriber_hash":{"value":"534245130707274","passed":false,"description":"MailerLite email tracking"},"_hsenc":{"value":"534245130707274","passed":false,"description":"HubSpot tracking parameter"},"__hssc":{"value":"534245130707274","passed":false,"description":"HubSpot tracking parameter"},"__hstc":{"value":"534245130707274","passed":false,"description":"HubSpot tracking parameter"},"__hsfp":{"value":"534245130707274","passed":false,"description":"HubSpot tracking parameter"},"hsCtaTracking":{"value":"534245130707274","passed":false,"description":"HubSpot tracking parameter"},"mkt_tok":{"value":"534245130707274","passed":false,"description":"Adobe Marketo tracking parameter"}},"https":{"Upgradable image":{"passed":true,"result":"upgraded","description":"Checks to see if the browser attempts to upgrade an insecure address for an image to HTTPS whenever possible."},"Upgradable script":{"passed":true,"result":"blocked","description":"Checks to see if the browser attempts to upgrade an insecure address for an script to HTTPS whenever possible."},"Upgradable hyperlink":{"upgraded":false,"passed":false,"description":"Checks to see if the user has clicked on a hyperlink to an insecure address, if the browser upgrades that address to HTTPS whenever possible."},"Upgradable address":{"upgraded":false,"passed":false,"description":"Checks to see if an insecure address entered into the browser's address bar is upgraded to HTTPS whenever possible."},"Insecure website warning":{"passed":false,"result":"Insecure website loaded","description":"Checks to see if the browser stops loading an insecure website and warns the user before giving them the option to continue. Known as HTTPS-Only Mode in some browsers."}},"fingerprinting":{"screenX":{"expression":"screenX","actual_value":0,"desired_min":0,"desired_max":10,"passed":true,"description":"Position, in pixels, of the left edge of the browser window on screen.","desired_min_value":0,"desired_max_value":10},"screenY":{"expression":"screenY","actual_value":0,"desired_min":0,"desired_max":10,"passed":true,"description":"Position, in pixels, of the top edge of the browser window on screen.","desired_min_value":0,"desired_max_value":10},"outerHeight":{"expression":"outerHeight","actual_value":561,"desired_min":"innerHeight - 10","desired_max":"innerHeight + 10","passed":false,"description":"Height of the browser window in pixels, including browser chrome.","desired_min_value":1456,"desired_max_value":1476},"screen.width":{"expression":"screen.width","actual_value":375,"desired_min":"innerWidth - 10","desired_max":"innerWidth + 10","passed":false,"description":"Width of the user's screen, in pixels.","desired_min_value":970,"desired_max_value":990},"screen.height":{"expression":"screen.height","actual_value":667,"desired_min":"innerHeight - 10","desired_max":"innerHeight + 10","passed":false,"description":"Height of the user's screen, in pixels.","desired_min_value":1456,"desired_max_value":1476},"Media query screen width":{"name":"Media query screen width","actual_value":375,"desired_min":"innerWidth - 10","desired_max":"innerWidth + 10","passed":false,"description":"Width of the user's screen in pixels.","desired_min_value":970,"desired_max_value":990},"Media query screen height":{"name":"Media query screen height","actual_value":667,"desired_min":"innerHeight - 10","desired_max":"innerHeight + 10","passed":false,"description":"Height of the user's screen in pixels.","desired_min_value":1456,"desired_max_value":1476}},"navigation":{"sessionStorage":{"write":"(secret) => sessionStorage.setItem(\"secret\", secret)","read":"() => sessionStorage.getItem(\"secret\")","unsupported":false,"readSameFirstParty":"02f50774-fc60-4de1-8b21-868329d0182c","readDifferentFirstParty":null,"passed":true,"testFailed":false,"description":"The sessionStorage API is similar to the localStorage API, but it does not persist across tabs or across browser sessions. Nonetheless, it can be used to track users if they navigate from one website to another. This tracking can be thwarted by partitioning sessionStorage between websites."},"window.name":{"write":"(secret) => window.name = \"name_\" + secret","read":"() => window.name","unsupported":false,"readSameFirstParty":"name_02f50774-fc60-4de1-8b21-868329d0182c","readDifferentFirstParty":"","passed":true,"testFailed":false,"description":"The window.name API allows websites to store data that will persist after the user has navigated the tab to a different website. This mechanism could be partitioned so that data is not allowed to persist between websites."},"document.referrer":{"write":"(secret) => { /* do nothing */ }","read":"() => document.referrer","unsupported":false,"readSameFirstParty":"https://test-pages.privacytests2.org/","readDifferentFirstParty":"https://test-pages.privacytests2.org/","passed":false,"testFailed":false,"description":"The Referer [sic] request header is a mechanism used by browsers to let a website know where the user is visiting from. This header is inherently tracking users across websites. In recent times, browsers have switched to a policy of trimming a referrer to convey less tracking information, but Referer continues to convey cross-site tracking data by default."}},"supercookies":{"cookie (JS)":{"write":"(secret) => {\n document.cookie = `secret=${secret}_js; max-age=3600; SameSite=None; Secure`;\n }","read":"() => document.cookie ? document.cookie.match(/secret=([\\w-]+)/)[1] : null","unsupported":false,"readSameFirstParty":"02f50774-fc60-4de1-8b21-868329d0182c_js","readDifferentFirstParty":null,"passed":true,"testFailed":false,"description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them."},"cookie (HTTP)":{"write":"async (secret) => {\n // Request a page that will send an HTTPOnly 'set-cookie' response header with secret value.\n await fetch(`${baseURI}cookie?secret=${secret}_http`);\n }","read":"async () => {\n // Test if we now send a requests with a 'cookie' header containing the secret.\n let response = await fetch(`${baseURI}headers`);\n let cookie = (await response.json())[\"cookie\"];\n return cookie ? cookie.match(/secret=([\\w-]+)/)[1]: null;\n }","unsupported":false,"readSameFirstParty":"02f50774-fc60-4de1-8b21-868329d0182c_http","readDifferentFirstParty":null,"passed":true,"testFailed":false,"description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them."},"localStorage":{"write":"(secret) => localStorage.setItem(\"secret\", secret)","read":"() => localStorage.getItem(\"secret\")","unsupported":false,"readSameFirstParty":"02f50774-fc60-4de1-8b21-868329d0182c","readDifferentFirstParty":null,"passed":true,"testFailed":false,"description":"The localStorage API gives websites access to a key-value database that will remain available across visits. If the localStorage API is not partitioned or blocked, it can also be used to track users across websites."},"indexedDB":{"write":"async (secret) => {\n try {\n return await IdbKeyVal.set(\"secret\", secret);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"() => IdbKeyVal.get(\"secret\")","unsupported":false,"readSameFirstParty":"02f50774-fc60-4de1-8b21-868329d0182c","passed":true,"testFailed":false,"description":"The IndexedDB API exposes a transactional database to web pages. That database can be used to track users across websites, unless it is partitioned."},"SharedWorker":{"write":"async (secret) => {\n try {\n let worker = new SharedWorker(\"supercookies_sharedworker.js\");\n worker.port.start();\n// console.log(\"worker\", worker);\n const messagePromise = new Promise((resolve) => {\n worker.port.onmessage = (e) => resolve(e.data);\n });\n worker.port.postMessage(secret);\n await messagePromise;\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n let worker = new SharedWorker(\"supercookies_sharedworker.js\");\n worker.port.start();\n const messagePromise = new Promise((resolve, reject) => {\n worker.port.onmessage = (e) => resolve(e.data);\n setTimeout(() => reject(new Error(\"no SharedWorker message received\")), 200);\n });\n worker.port.postMessage(\"request\");\n const message = await messagePromise;\n if (message === \"none\") {\n throw new Error(\"Unsupported\");\n }\n return message;\n }","unsupported":true,"readSameFirstParty":"Error: Unsupported","readDifferentFirstParty":"Error: Unsupported","testFailed":false,"description":"The SharedWorker API allows scripts from multiple tabs to share a background thread of computation. If SharedWorker is not partitioned, then it can be abused to shared data between websites in your browser."},"blob":{"write":"(secret) => {\n try {\n let blobURL = URL.createObjectURL(new Blob([secret]));\n fetch(`${baseURI}blob?mode=write&key=${secret}&blobUrl=${encodeURIComponent(blobURL)}`);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async (secret) => {\n let response = await fetch(`${baseURI}blob?mode=read&key=${secret}`);\n let result = await response.json();\n let blobUrl = decodeURIComponent(result.blobUrl);\n let blobResponse = await fetch(blobUrl);\n return blobResponse.text();\n }","unsupported":false,"readSameFirstParty":"Error: Load failed","readDifferentFirstParty":"Error: Load failed","testFailed":true,"description":"A 'blob URL' is a local reference to some raw data. Trackers can use a blob URL to share data between websites."},"BroadcastChannel":{"write":"(secret) => {\n try {\n let bc = new BroadcastChannel(\"secrets\");\n bc.onmessage = (event) => {\n if (event.data === \"request\") {\n bc.postMessage(secret);\n }\n };\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"() =>\n new Promise((resolve, reject) => {\n let bc = new BroadcastChannel(\"secrets\");\n bc.onmessage = (event) => {\n if (event.data !== \"request\") {\n resolve(event.data);\n }\n };\n bc.postMessage(\"request\");\n setTimeout(() => reject({message: \"no BroadcastChannel message\"}), 3000);\n })","unsupported":false,"readSameFirstParty":"Error: no BroadcastChannel message","readDifferentFirstParty":"Error: no BroadcastChannel message","testFailed":true,"description":"A BroadcastChannel is designed to send messages between tabs. In some browsers it can be used for cross-site communication and tracking."},"fetch cache":{"write":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n return key;\n }","read":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n let countResponse = await fetch(testURI(\"ctr\", \"fetch\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","unsupported":false,"readSameFirstParty":"1","readDifferentFirstParty":"2","passed":true,"testFailed":false,"description":"When a resource is received via the Fetch API, it is frequently cached. That cache can potentially be abused for cross-site tracking."},"XMLHttpRequest cache":{"write":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n return key;\n }","read":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n let countResponse = await fetch(testURI(\"ctr\", \"xhr\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","unsupported":false,"readSameFirstParty":"1","readDifferentFirstParty":"2","passed":true,"testFailed":false,"description":"Similar to the newer Fetch API, any resource received may be cached by the browser. The cache is potentially vulnerable to cross-site tracking attack."},"iframe cache":{"write":"(key) => new Promise((resolve, reject) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n iframe.addEventListener(\"load\", () => resolve(key), {once: true});\n iframe.src = testURI(\"resource\", \"page\", key);\n })","read":"async (key) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n let iframeLoadPromise = new Promise((resolve, reject) => {\n iframe.addEventListener(\"load\", resolve, {once: true});\n });\n let address = testURI(\"resource\", \"page\", key);\n iframe.src = address;\n await iframeLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"page\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","unsupported":false,"readSameFirstParty":"1","readDifferentFirstParty":"2","passed":true,"testFailed":false,"description":"An iframe is an element in a web page than allows websites to embed a second web page. Caching of this web page could be abused for cross-site tracking."},"CacheStorage":{"write":"async (key) => {\n try {\n let cache = await caches.open(\"supercookies\");\n cache.addAll([`test.css?key=${key}`]);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n let cache = await caches.open(\"supercookies\");\n let cacheKeys = await cache.keys();\n let url = cacheKeys[0].url;\n return (new URL(url)).searchParams.get(\"key\");\n }","unsupported":false,"readSameFirstParty":"02f50774-fc60-4de1-8b21-868329d0182c","readDifferentFirstParty":"Error: undefined is not an object (evaluating 'cacheKeys[0].url')","passed":true,"testFailed":false,"description":"The Cache API is a content storage mechanism originally introduced to support ServiceWorkers. If the same Cache object is accessible to multiple websites, it can be abused to track users."},"favicon cache":{"write":"(key) => key","read":"async (key) => {\n // Wait for the favicon to load (defined in supercookies.html)\n await sleepMs(2000);\n let response = await fetch(\n testURI(\"ctr\", \"favicon\", key), {\"cache\": \"reload\"});\n let count = (await response.text()).trim();\n if (count === \"0\") {\n throw new Error(\"No requests received\");\n }\n return count;\n }","unsupported":false,"readSameFirstParty":"1","readDifferentFirstParty":"1","passed":false,"testFailed":false,"description":"A favicon is an icon that represents a website, typically shown in browser tab and bookmarks menu. If the favicon cache is not partitioned, it can be used to track users across websites."},"locks":{"write":"async (key) => {\n if (navigator.locks) {\n navigator.locks.request(key, lock => new Promise((f,r) => {}));\n let queryResult = await navigator.locks.query();\n return queryResult.held[0].clientId;\n } else {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n if (navigator.locks) {\n let queryResult = await navigator.locks.query();\n return queryResult.held[0].name;\n }\n }","unsupported":false,"readSameFirstParty":"Error: undefined is not an object (evaluating 'queryResult.held[0].name')","readDifferentFirstParty":"Error: undefined is not an object (evaluating 'queryResult.held[0].name')","testFailed":true,"description":"navigator.locks (only supported in some browsers) allows scripts on multiple tabs to coordinate. If this API is not partitioned, it can be used for cross-site tracking."},"TLS Session ID":{"write":"async () => {\n let results = await fetch(\"https://tls.privacytests2.org:8900/\");\n return (await results.json()).sessionId;\n }","read":"async () => {\n let results = await fetch(\"https://tls.privacytests2.org:8900/\");\n return (await results.json()).sessionId;\n }","unsupported":false,"readSameFirstParty":"ec82a0a66737a1b049a0b8e7d3d177d99f7d0fcc5af2b8e9b5880003077f6d09","readDifferentFirstParty":"d7bfcfbfda8263ef91ca048d0d68228025ded6e6b5ca3cfee108f1956e9a3c7b","passed":true,"testFailed":false,"description":"The TLS protocol is used by HTTPS to make connections secure. If the browser were to re-use a TLS session, then the session ID could be used to track users across websites."},"H1 connection":{"write":"async (secret) => {\n await fetch(`https://h1.privacytests2.org:8901/?mode=write&secret=${secret}`, {cache: \"no-store\"});\n }","read":"async () => {\n let response = await fetch(`https://h1.privacytests2.org:8901/?mode=read`, {cache: \"no-store\"});\n return await response.text();\n }","unsupported":false,"readSameFirstParty":"02f50774-fc60-4de1-8b21-868329d0182c","readDifferentFirstParty":"","passed":true,"testFailed":false,"description":"HTTP/1.x are the classic web connection protocols. If these connections are re-used across websites, they can be used to track users."},"H2 connection":{"write":"async (secret) => {\n await fetch(`https://h2.privacytests2.org:8902/?mode=write&secret=${secret}`, {cache: \"no-store\"});\n }","read":"async () => {\n let response = await fetch(`https://h2.privacytests2.org:8902/?mode=read`, {cache: \"no-store\"});\n return await response.text();\n }","unsupported":false,"readSameFirstParty":"02f50774-fc60-4de1-8b21-868329d0182c","readDifferentFirstParty":"","passed":true,"testFailed":false,"description":"HTTP/2 is a web connection protocol introduced in 2015. Some browsers re-use HTTP/2 connections across websites and can thus be used to track users."},"H3 connection":{"write":"async (secret) => {\n // Ensure that we can switch over to h3 via alt-svc:\n for (let i = 0; i<3; ++i) {\n await fetch(`https://h3.privacytests2.org:4434/connection_id`, {cache: \"no-store\"});\n await sleepMs(500);\n }\n // Are we now connecting over h3?\n let response = await fetch(`https://h3.privacytests2.org:4434/connection_id`, {cache: \"no-store\"});\n let text = await response.text();\n // Empty response text indicates we are not connecting over h3:\n if (text.trim() === \"\") {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n let response = await fetch(`https://h3.privacytests2.org:4434/connection_id`);\n return await response.text();\n }","unsupported":true,"readSameFirstParty":"","readDifferentFirstParty":"","testFailed":false,"description":"HTTP/3 is a new standard HTTP connection protocol, still in draft but widely supported by browsers. If it is not partitioned, it can be used to track users across websites."},"CookieStore":{"write":"(data) => {\n const msPerHour = 60 * 60 * 1000;\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n window.cookieStore.set({\n name: \"partition_test\",\n value: data,\n expires: Date.now() + msPerHour,\n sameSite: \"none\"\n });\n }","read":"async () => {\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n const cookie = await window.cookieStore.get(\"partition_test\");\n if (!cookie) {\n return null;\n }\n return cookie.value;\n }","unsupported":true,"readSameFirstParty":"Error: Unsupported","readDifferentFirstParty":"Error: Unsupported","testFailed":false,"description":"The Cookie Store API is an alternative asynchronous API for managing cookies, supported by some browsers."},"getDirectory":{"write":"async (secret) => {\n try {\n const root = await navigator.storage.getDirectory();\n const fileHandle = await root.getFileHandle(\"secret.txt\", { create: true });\n const stream = await fileHandle.createWritable();\n await stream.write(secret);\n await stream.close();\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n try {\n const root = await navigator.storage.getDirectory();\n const fileHandle = await root.getFileHandle(\"secret.txt\");\n const file = await fileHandle.getFile();\n return file.text();\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","unsupported":true,"readSameFirstParty":"","readDifferentFirstParty":"Error: Unsupported","testFailed":false,"description":"navigator.storage.getDirectory exposes a location for storing files to web content. In some cases, these files may be shared across tabs."},"ServiceWorker":{"write":"async (key) => {\n if (!navigator.serviceWorker) {\n throw new Error(\"Unsupported\");\n }\n let registration = await navigator.serviceWorker.register(\n 'serviceWorker.js');\n console.log(registration);\n await navigator.serviceWorker.ready;\n console.log(\"service worker ready\");\n await sleepMs(100);\n await fetch(`serviceworker-write?secret=${key}`);\n }","read":"async () => {\n console.log(\"trying to register the serviceworker now...\");\n const registration = await Promise.race([\n navigator.serviceWorker.register('serviceWorker.js'),\n sleepMs(500)\n ]);\n if (registration === undefined) {\n // We timed out or otherwise failed.\n throw new Error(\"ServiceWorker registration failed\");\n }\n console.log(registration);\n await navigator.serviceWorker.ready;\n console.log(\"service worker ready\");\n await sleepMs(100);\n let response = await fetch(\"serviceworker-read\");\n return await response.text();\n }","unsupported":false,"readSameFirstParty":"","readDifferentFirstParty":"","testFailed":true,"description":"The ServiceWorker API allows websites to run code in the background and store content in the browser for offline use. If a ServiceWorker can be accessed from multiple websites, it can be abused to track users across sites."},"CSS cache":{"write":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return key;\n }","read":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return fontFamily;\n }","unsupported":false,"readSameFirstParty":"fake_049793877173841095","readDifferentFirstParty":"fake_6478738261288255","passed":true,"testFailed":false,"description":"CSS stylesheets are cached, and if that cache is shared between websites, it can be used to track users across sites."},"font cache":{"write":"async (key) => {\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } body { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n return key;\n }","read":"async (key) => {\n const text = document.createElement(\"span\");\n text.id = \"text\";\n text.innerText = \"test\";\n document.body.appendChild(text);\n const originalWidth = text.getBoundingClientRect().width;\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } #text { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n let newWidth;\n do {\n await sleepMs(100);\n newWidth = text.getBoundingClientRect().width;\n } while (newWidth < 0 || newWidth === originalWidth)\n let response = await fetch(\n testURI(\"ctr\", \"font\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","unsupported":false,"readSameFirstParty":"2","readDifferentFirstParty":"3","passed":true,"testFailed":false,"description":"Web fonts are sometimes stored in their own cache, which is vulnerable to being abused for cross-site tracking."},"image cache":{"write":"(key) => new Promise((resolve, reject) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n img.addEventListener(\"load\", () => resolve(key), {once: true});\n img.src = testURI(\"resource\", \"image\", key);\n })","read":"async (key) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n let imgLoadPromise = new Promise((resolve, reject) => {\n img.addEventListener(\"load\", resolve, {once: true});\n });\n img.src = testURI(\"resource\", \"image\", key);\n await imgLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"image\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","unsupported":false,"readSameFirstParty":"2","readDifferentFirstParty":"3","passed":true,"testFailed":false,"description":"Caching of images in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking."},"script cache":{"write":"(key) => new Promise((resolve, reject) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n script.addEventListener(\"load\", () => resolve(key), {once: true});\n script.src = testURI(\"resource\", \"script\", key);\n })","read":"async (key) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n let scriptLoadPromise = new Promise((resolve, reject) => {\n script.addEventListener(\"load\", resolve, {once: true});\n });\n script.src = testURI(\"resource\", \"script\", key);\n await scriptLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"script\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","unsupported":false,"readSameFirstParty":"2","readDifferentFirstParty":"3","passed":true,"testFailed":false,"description":"Caching of scripts in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking."},"prefetch cache":{"write":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n return key;\n }","read":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n await sleepMs(500);\n let response = await fetch(\n testURI(\"ctr\", \"prefetch\", key), {\"cache\": \"reload\"});\n let countString = (await response.text()).trim();\n if (parseInt(countString) === 0) {\n throw new Error(\"No requests received\");\n }\n return countString;\n }","unsupported":true,"readSameFirstParty":"Error: No requests received","readDifferentFirstParty":"Error: No requests received","testFailed":false,"description":"A suggests to browsers they should fetch a resource ahead of time and cache it. But if browsers don't partition this cache, it can be used to track users across websites."},"Alt-Svc":{"write":"async () => {\n // Clear Alt-Svc caching first.\n let responseText = \"\";\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/clear\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after clear:\", responseText);\n // Store \"h3\" state in Alt-Svc cache\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/set\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after set:\", responseText);\n }","read":"async () => {\n const protocol = await fetchText(altSvcOrigin + \"/protocol\");\n if ((new URL(location)).searchParams.get(\"thirdparty\") === \"same\") {\n if (protocol !== \"h3\") {\n throw new Error(\"Unsupported\");\n }\n }\n return protocol;\n }","unsupported":true,"readSameFirstParty":"Error: Unsupported","readDifferentFirstParty":"h3","testFailed":false,"description":"Alt-Svc allows the server to indicate to the web browser that a resource should be loaded on a different server. Because this is a persistent setting, it could be used to track users across websites if it is not correctly partitioned."},"HSTS cache":{"description":"The HTTP Strict-Transport-Security response header allows a website to signal that it should only be accessed via HTTPS. The browser remembers this directive in a database, but if this database is not partitioned, then it can be used to track users across websites.\"","passed":true,"unsupported":false,"testFailed":false,"readDifferentFirstParty":"Used http","readSameFirstParty":"not tested","write":"set HSTS flag","read":"read HSTS flag"},"HSTS cache (fetch)":{"description":"The HTTP Strict-Transport-Security response header allows a website to signal that it should only be accessed via HTTPS. The browser remembers this directive in a database, but if this database is not partitioned, then it can be used to track users across websites.\"","passed":true,"unsupported":false,"testFailed":false,"readDifferentFirstParty":"Used http","readSameFirstParty":"not tested","write":"set HSTS flag","read":"read HSTS flag"}},"trackers":{"Google (third-party ad pixel)":{"url":"https://www.google.com/pagead/1p-user-list/","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://www.google.com/pagead/1p-user-list/"},"Google Tag Manager":{"url":"https://www.googletagmanager.com/gtag.js?id=GTM-NX4SMZL","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://www.googletagmanager.com/gtag.js?id=GTM-NX4SMZL"},"DoubleClick (Google)":{"url":"https://securepubads.g.doubleclick.net/static/glade.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://securepubads.g.doubleclick.net/static/glade.js"},"Google Analytics":{"url":"https://google-analytics.com/urchin.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://google-analytics.com/urchin.js"},"Facebook tracking":{"url":"https://connect.facebook.net/en_US/fbevents.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://connect.facebook.net/en_US/fbevents.js"},"Amazon adsystem":{"url":"https://s.amazon-adsystem.com/dcm","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://s.amazon-adsystem.com/dcm"},"Scorecard Research Beacon":{"url":"https://sb.scorecardresearch.com/internal-c2/default/cs.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://sb.scorecardresearch.com/internal-c2/default/cs.js"},"New Relic":{"url":"https://js-agent.newrelic.com/nr-1212.min.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://js-agent.newrelic.com/nr-1212.min.js"},"Criteo":{"url":"https://dis.criteo.com/dis/rtb/appnexus/cookiematch.aspx","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://dis.criteo.com/dis/rtb/appnexus/cookiematch.aspx"},"Adobe":{"url":"https://munchkin.marketo.net/munchkin.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://munchkin.marketo.net/munchkin.js"},"Adobe Audience Manager":{"url":"https://dpm.demdex.net/ibs","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://dpm.demdex.net/ibs"},"AppNexus":{"url":"https://ib.adnxs.com/px?id=178248&t=1","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://ib.adnxs.com/px?id=178248&t=1"},"Twitter pixel":{"url":"https://t.co/i/adsct","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://t.co/i/adsct"},"Bing Ads":{"url":"https://bat.bing.com/bat.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://bat.bing.com/bat.js"},"Taboola":{"url":"https://trc.taboola.com/futureplc-tomsguide/trc/3/json","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://trc.taboola.com/futureplc-tomsguide/trc/3/json"},"Index Exchange":{"url":"https://dsum-sec.casalemedia.com/crum?cm_dsp_id=10&external_user_id=629685505537&C=1","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://dsum-sec.casalemedia.com/crum?cm_dsp_id=10&external_user_id=629685505537&C=1"},"Yandex Ads":{"url":"https://yandex.ru/ads/system/header-bidding.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://yandex.ru/ads/system/header-bidding.js"},"Quantcast":{"url":"https://pixel.quantserve.com/pixel","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://pixel.quantserve.com/pixel"},"Chartbeat":{"url":"https://static.chartbeat.com/js/chartbeat.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://static.chartbeat.com/js/chartbeat.js"}}},"timeStarted":"2024-03-31T23:36:18.261Z","reportedVersion":"123.2420.56","os":"Darwin","os_version":"Darwin Kernel Version 23.4.0: Wed Feb 21 21:44:06 PST 2024; root:xnu-10063.101.15~2/RELEASE_ARM64_T8103"},{"browser":"edge","incognito":false,"tor":false,"nightly":false,"testResults":{"session_3p":{"cookie (JS)":{"unsupported":true,"testFailed":false,"write":"(secret) => {\n document.cookie = `secret=${secret}_js; max-age=3600; SameSite=None; Secure`;\n }","read":"() => document.cookie ? document.cookie.match(/secret=([\\w-]+)/)[1] : null","description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them.","readSameSession":null,"readDifferentSession":null},"cookie (HTTP)":{"unsupported":true,"testFailed":false,"write":"async (secret) => {\n // Request a page that will send an HTTPOnly 'set-cookie' response header with secret value.\n await fetch(`${baseURI}cookie?secret=${secret}_http`);\n }","read":"async () => {\n // Test if we now send a requests with a 'cookie' header containing the secret.\n let response = await fetch(`${baseURI}headers`);\n let cookie = (await response.json())[\"cookie\"];\n return cookie ? cookie.match(/secret=([\\w-]+)/)[1]: null;\n }","description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them.","readSameSession":null,"readDifferentSession":null},"localStorage":{"unsupported":false,"passed":true,"testFailed":false,"write":"(secret) => localStorage.setItem(\"secret\", secret)","read":"() => localStorage.getItem(\"secret\")","description":"The localStorage API gives websites access to a key-value database that will remain available across visits. If the localStorage API is not partitioned or blocked, it can also be used to track users across websites.","readSameSession":"fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0_3p","readDifferentSession":null},"indexedDB":{"unsupported":false,"passed":true,"testFailed":false,"write":"async (secret) => {\n try {\n return await IdbKeyVal.set(\"secret\", secret);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"() => IdbKeyVal.get(\"secret\")","description":"The IndexedDB API exposes a transactional database to web pages. That database can be used to track users across websites, unless it is partitioned.","readSameSession":"fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0_3p"},"fetch cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n return key;\n }","read":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n let countResponse = await fetch(testURI(\"ctr\", \"fetch\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","description":"When a resource is received via the Fetch API, it is frequently cached. That cache can potentially be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"XMLHttpRequest cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n return key;\n }","read":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n let countResponse = await fetch(testURI(\"ctr\", \"xhr\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","description":"Similar to the newer Fetch API, any resource received may be cached by the browser. The cache is potentially vulnerable to cross-site tracking attack.","readSameSession":"1","readDifferentSession":"1"},"iframe cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n iframe.addEventListener(\"load\", () => resolve(key), {once: true});\n iframe.src = testURI(\"resource\", \"page\", key);\n })","read":"async (key) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n let iframeLoadPromise = new Promise((resolve, reject) => {\n iframe.addEventListener(\"load\", resolve, {once: true});\n });\n let address = testURI(\"resource\", \"page\", key);\n iframe.src = address;\n await iframeLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"page\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"An iframe is an element in a web page than allows websites to embed a second web page. Caching of this web page could be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"CacheStorage":{"unsupported":false,"passed":true,"testFailed":false,"write":"async (key) => {\n try {\n let cache = await caches.open(\"supercookies\");\n cache.addAll([`test.css?key=${key}`]);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n let cache = await caches.open(\"supercookies\");\n let cacheKeys = await cache.keys();\n let url = cacheKeys[0].url;\n return (new URL(url)).searchParams.get(\"key\");\n }","description":"The Cache API is a content storage mechanism originally introduced to support ServiceWorkers. If the same Cache object is accessible to multiple websites, it can be abused to track users.","readSameSession":"fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0_3p","readDifferentSession":"Error: undefined is not an object (evaluating 'cacheKeys[0].url')"},"favicon cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => key","read":"async (key) => {\n // Wait for the favicon to load (defined in supercookies.html)\n await sleepMs(2000);\n let response = await fetch(\n testURI(\"ctr\", \"favicon\", key), {\"cache\": \"reload\"});\n let count = (await response.text()).trim();\n if (count === \"0\") {\n throw new Error(\"No requests received\");\n }\n return count;\n }","description":"A favicon is an icon that represents a website, typically shown in browser tab and bookmarks menu. If the favicon cache is not partitioned, it can be used to track users across websites.","readSameSession":"1","readDifferentSession":"1"},"CookieStore":{"unsupported":true,"testFailed":false,"write":"(data) => {\n const msPerHour = 60 * 60 * 1000;\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n window.cookieStore.set({\n name: \"partition_test\",\n value: data,\n expires: Date.now() + msPerHour,\n sameSite: \"none\"\n });\n }","read":"async () => {\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n const cookie = await window.cookieStore.get(\"partition_test\");\n if (!cookie) {\n return null;\n }\n return cookie.value;\n }","description":"The Cookie Store API is an alternative asynchronous API for managing cookies, supported by some browsers.","readSameSession":"Error: Unsupported","readDifferentSession":"Error: Unsupported"},"CSS cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return key;\n }","read":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return fontFamily;\n }","description":"CSS stylesheets are cached, and if that cache is shared between websites, it can be used to track users across sites.","readSameSession":"fake_7433174956497555","readDifferentSession":"fake_7433174956497555"},"image cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n img.addEventListener(\"load\", () => resolve(key), {once: true});\n img.src = testURI(\"resource\", \"image\", key);\n })","read":"async (key) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n let imgLoadPromise = new Promise((resolve, reject) => {\n img.addEventListener(\"load\", resolve, {once: true});\n });\n img.src = testURI(\"resource\", \"image\", key);\n await imgLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"image\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Caching of images in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"script cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n script.addEventListener(\"load\", () => resolve(key), {once: true});\n script.src = testURI(\"resource\", \"script\", key);\n })","read":"async (key) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n let scriptLoadPromise = new Promise((resolve, reject) => {\n script.addEventListener(\"load\", resolve, {once: true});\n });\n script.src = testURI(\"resource\", \"script\", key);\n await scriptLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"script\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Caching of scripts in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"font cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } body { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n return key;\n }","read":"async (key) => {\n const text = document.createElement(\"span\");\n text.id = \"text\";\n text.innerText = \"test\";\n document.body.appendChild(text);\n const originalWidth = text.getBoundingClientRect().width;\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } #text { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n let newWidth;\n do {\n await sleepMs(100);\n newWidth = text.getBoundingClientRect().width;\n } while (newWidth < 0 || newWidth === originalWidth)\n let response = await fetch(\n testURI(\"ctr\", \"font\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Web fonts are sometimes stored in their own cache, which is vulnerable to being abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"prefetch cache":{"unsupported":true,"testFailed":false,"write":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n return key;\n }","read":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n await sleepMs(500);\n let response = await fetch(\n testURI(\"ctr\", \"prefetch\", key), {\"cache\": \"reload\"});\n let countString = (await response.text()).trim();\n if (parseInt(countString) === 0) {\n throw new Error(\"No requests received\");\n }\n return countString;\n }","description":"A suggests to browsers they should fetch a resource ahead of time and cache it. But if browsers don't partition this cache, it can be used to track users across websites.","readSameSession":"Error: No requests received","readDifferentSession":"Error: No requests received"},"Alt-Svc":{"unsupported":true,"testFailed":false,"write":"async () => {\n // Clear Alt-Svc caching first.\n let responseText = \"\";\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/clear\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after clear:\", responseText);\n // Store \"h3\" state in Alt-Svc cache\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/set\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after set:\", responseText);\n }","read":"async () => {\n const protocol = await fetchText(altSvcOrigin + \"/protocol\");\n if ((new URL(location)).searchParams.get(\"thirdparty\") === \"same\") {\n if (protocol !== \"h3\") {\n throw new Error(\"Unsupported\");\n }\n }\n return protocol;\n }","description":"Alt-Svc allows the server to indicate to the web browser that a resource should be loaded on a different server. Because this is a persistent setting, it could be used to track users across websites if it is not correctly partitioned.","readSameSession":"h2","readDifferentSession":"h3"}},"session_1p":{"cookie (JS)":{"unsupported":false,"passed":false,"testFailed":false,"write":"(secret) => {\n document.cookie = `secret=${secret}_js; max-age=3600; SameSite=None; Secure`;\n }","read":"() => document.cookie ? document.cookie.match(/secret=([\\w-]+)/)[1] : null","description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them.","readSameSession":"fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0_1p_js","readDifferentSession":"fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0_1p_js"},"cookie (HTTP)":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (secret) => {\n // Request a page that will send an HTTPOnly 'set-cookie' response header with secret value.\n await fetch(`${baseURI}cookie?secret=${secret}_http`);\n }","read":"async () => {\n // Test if we now send a requests with a 'cookie' header containing the secret.\n let response = await fetch(`${baseURI}headers`);\n let cookie = (await response.json())[\"cookie\"];\n return cookie ? cookie.match(/secret=([\\w-]+)/)[1]: null;\n }","description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them.","readSameSession":"fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0_1p_http","readDifferentSession":"fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0_1p_http"},"localStorage":{"unsupported":false,"passed":false,"testFailed":false,"write":"(secret) => localStorage.setItem(\"secret\", secret)","read":"() => localStorage.getItem(\"secret\")","description":"The localStorage API gives websites access to a key-value database that will remain available across visits. If the localStorage API is not partitioned or blocked, it can also be used to track users across websites.","readSameSession":"fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0_1p","readDifferentSession":"fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0_1p"},"indexedDB":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (secret) => {\n try {\n return await IdbKeyVal.set(\"secret\", secret);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"() => IdbKeyVal.get(\"secret\")","description":"The IndexedDB API exposes a transactional database to web pages. That database can be used to track users across websites, unless it is partitioned.","readSameSession":"fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0_1p","readDifferentSession":"fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0_1p"},"fetch cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n return key;\n }","read":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n let countResponse = await fetch(testURI(\"ctr\", \"fetch\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","description":"When a resource is received via the Fetch API, it is frequently cached. That cache can potentially be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"XMLHttpRequest cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n return key;\n }","read":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n let countResponse = await fetch(testURI(\"ctr\", \"xhr\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","description":"Similar to the newer Fetch API, any resource received may be cached by the browser. The cache is potentially vulnerable to cross-site tracking attack.","readSameSession":"1","readDifferentSession":"1"},"iframe cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n iframe.addEventListener(\"load\", () => resolve(key), {once: true});\n iframe.src = testURI(\"resource\", \"page\", key);\n })","read":"async (key) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n let iframeLoadPromise = new Promise((resolve, reject) => {\n iframe.addEventListener(\"load\", resolve, {once: true});\n });\n let address = testURI(\"resource\", \"page\", key);\n iframe.src = address;\n await iframeLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"page\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"An iframe is an element in a web page than allows websites to embed a second web page. Caching of this web page could be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"CacheStorage":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n try {\n let cache = await caches.open(\"supercookies\");\n cache.addAll([`test.css?key=${key}`]);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n let cache = await caches.open(\"supercookies\");\n let cacheKeys = await cache.keys();\n let url = cacheKeys[0].url;\n return (new URL(url)).searchParams.get(\"key\");\n }","description":"The Cache API is a content storage mechanism originally introduced to support ServiceWorkers. If the same Cache object is accessible to multiple websites, it can be abused to track users.","readSameSession":"18747aa0-a493-4b2f-8684-a70dc7fadf6a_1p","readDifferentSession":"18747aa0-a493-4b2f-8684-a70dc7fadf6a_1p"},"favicon cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => key","read":"async (key) => {\n // Wait for the favicon to load (defined in supercookies.html)\n await sleepMs(2000);\n let response = await fetch(\n testURI(\"ctr\", \"favicon\", key), {\"cache\": \"reload\"});\n let count = (await response.text()).trim();\n if (count === \"0\") {\n throw new Error(\"No requests received\");\n }\n return count;\n }","description":"A favicon is an icon that represents a website, typically shown in browser tab and bookmarks menu. If the favicon cache is not partitioned, it can be used to track users across websites.","readSameSession":"1","readDifferentSession":"1"},"CookieStore":{"unsupported":true,"testFailed":false,"write":"(data) => {\n const msPerHour = 60 * 60 * 1000;\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n window.cookieStore.set({\n name: \"partition_test\",\n value: data,\n expires: Date.now() + msPerHour,\n sameSite: \"none\"\n });\n }","read":"async () => {\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n const cookie = await window.cookieStore.get(\"partition_test\");\n if (!cookie) {\n return null;\n }\n return cookie.value;\n }","description":"The Cookie Store API is an alternative asynchronous API for managing cookies, supported by some browsers.","readSameSession":"Error: Unsupported","readDifferentSession":"Error: Unsupported"},"CSS cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return key;\n }","read":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return fontFamily;\n }","description":"CSS stylesheets are cached, and if that cache is shared between websites, it can be used to track users across sites.","readSameSession":"fake_41543632084179327","readDifferentSession":"fake_41543632084179327"},"image cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n img.addEventListener(\"load\", () => resolve(key), {once: true});\n img.src = testURI(\"resource\", \"image\", key);\n })","read":"async (key) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n let imgLoadPromise = new Promise((resolve, reject) => {\n img.addEventListener(\"load\", resolve, {once: true});\n });\n img.src = testURI(\"resource\", \"image\", key);\n await imgLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"image\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Caching of images in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"script cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n script.addEventListener(\"load\", () => resolve(key), {once: true});\n script.src = testURI(\"resource\", \"script\", key);\n })","read":"async (key) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n let scriptLoadPromise = new Promise((resolve, reject) => {\n script.addEventListener(\"load\", resolve, {once: true});\n });\n script.src = testURI(\"resource\", \"script\", key);\n await scriptLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"script\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Caching of scripts in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"font cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } body { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n return key;\n }","read":"async (key) => {\n const text = document.createElement(\"span\");\n text.id = \"text\";\n text.innerText = \"test\";\n document.body.appendChild(text);\n const originalWidth = text.getBoundingClientRect().width;\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } #text { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n let newWidth;\n do {\n await sleepMs(100);\n newWidth = text.getBoundingClientRect().width;\n } while (newWidth < 0 || newWidth === originalWidth)\n let response = await fetch(\n testURI(\"ctr\", \"font\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Web fonts are sometimes stored in their own cache, which is vulnerable to being abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"prefetch cache":{"unsupported":true,"testFailed":false,"write":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n return key;\n }","read":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n await sleepMs(500);\n let response = await fetch(\n testURI(\"ctr\", \"prefetch\", key), {\"cache\": \"reload\"});\n let countString = (await response.text()).trim();\n if (parseInt(countString) === 0) {\n throw new Error(\"No requests received\");\n }\n return countString;\n }","description":"A suggests to browsers they should fetch a resource ahead of time and cache it. But if browsers don't partition this cache, it can be used to track users across websites.","readSameSession":"Error: No requests received","readDifferentSession":"Error: No requests received"},"Alt-Svc":{"unsupported":true,"testFailed":false,"write":"async () => {\n // Clear Alt-Svc caching first.\n let responseText = \"\";\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/clear\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after clear:\", responseText);\n // Store \"h3\" state in Alt-Svc cache\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/set\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after set:\", responseText);\n }","read":"async () => {\n const protocol = await fetchText(altSvcOrigin + \"/protocol\");\n if ((new URL(location)).searchParams.get(\"thirdparty\") === \"same\") {\n if (protocol !== \"h3\") {\n throw new Error(\"Unsupported\");\n }\n }\n return protocol;\n }","description":"Alt-Svc allows the server to indicate to the web browser that a resource should be loaded on a different server. Because this is a persistent setting, it could be used to track users across websites if it is not correctly partitioned.","readSameSession":"h2","readDifferentSession":"h3"}},"misc":{"Tor enabled":{"IsTorExit":false,"passed":false,"description":"The Tor network sends the browser's web requests through a series of relays to hide a user's IP address, thereby helping to mask their identity and location. This test checks to see if the Tor network is being used by default."},"GPC enabled third-party":{"passed":false,"description":"The Global Privacy Control is an HTTP header that can be sent by a browser to instruct a visited website not to sell the user's personal data to other parties. This test checks to see if the GPC header is sent to third-party elements on the web page."},"ECH enabled":{"SNI_status":"plaintext","passed":false,"description":"Encrypted Client Hello (ECH) is a new protocol that hides the website you are visiting from third-party network eavesdroppers."},"Stream isolation":{"write":"() => {\n if (!usingTor) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n if (usingTor) {\n return ipAddress;\n } else {\n throw new Error(\"Unsupported\");\n }\n }","unsupported":true,"readSameFirstParty":"Error: Unsupported","readDifferentFirstParty":"Error: Unsupported","testFailed":false,"description":"Browsers that use Tor can use a different Tor circuit per top-level website."},"IP address leak":{"description":"IP addresses can be used to uniquely identify a large percentage of users. A proxy, VPN, or Tor can mask a user's IP address.","passed":false},"GPC enabled first-party":{"header value":"undefined","description":"The Global Privacy Control is an HTTP header that can be sent by a browser to instruct a website not to sell the user's personal data to third parties. This test checks to see if the GPC header is sent by default to the top-level website.","passed":false}},"query":{"fbclid":{"value":"534245130707274","passed":false,"description":"Facebook Click Identifier"},"gclid":{"value":"534245130707274","passed":false,"description":"Google Click Identifier"},"msclkid":{"value":"534245130707274","passed":false,"description":"Microsoft Click ID"},"mc_eid":{"value":"534245130707274","passed":false,"description":"Mailchimp Email ID (email recipient's address)"},"dclid":{"value":"534245130707274","passed":false,"description":"DoubleClick Click ID (Google)"},"oly_anon_id":{"value":"534245130707274","passed":false,"description":"Omeda marketing 'anonymous' customer id"},"oly_enc_id":{"value":"534245130707274","passed":false,"description":"Omeda marketing 'known' customer id"},"_openstat":{"value":"534245130707274","passed":false,"description":"Yandex tracking parameter"},"vero_conv":{"value":"534245130707274","passed":false,"description":"Vero tracking parameter"},"vero_id":{"value":"534245130707274","passed":false,"description":"Vero tracking parameter"},"wickedid":{"value":"534245130707274","passed":false,"description":"Wicked Reports e-commerce tracking"},"yclid":{"value":"534245130707274","passed":false,"description":"Yandex Click ID"},"__s":{"value":"534245130707274","passed":false,"description":"Drip.com email address tracking parameter"},"rb_clickid":{"value":"534245130707274","passed":false,"description":"Unknown high-entropy tracking parameter"},"s_cid":{"value":"534245130707274","passed":false,"description":"Adobe Site Catalyst tracking parameter"},"ml_subscriber":{"value":"534245130707274","passed":false,"description":"MailerLite email tracking"},"ml_subscriber_hash":{"value":"534245130707274","passed":false,"description":"MailerLite email tracking"},"_hsenc":{"value":"534245130707274","passed":false,"description":"HubSpot tracking parameter"},"__hssc":{"value":"534245130707274","passed":false,"description":"HubSpot tracking parameter"},"__hstc":{"value":"534245130707274","passed":false,"description":"HubSpot tracking parameter"},"__hsfp":{"value":"534245130707274","passed":false,"description":"HubSpot tracking parameter"},"hsCtaTracking":{"value":"534245130707274","passed":false,"description":"HubSpot tracking parameter"},"mkt_tok":{"value":"534245130707274","passed":false,"description":"Adobe Marketo tracking parameter"}},"https":{"Upgradable image":{"passed":true,"result":"upgraded","description":"Checks to see if the browser attempts to upgrade an insecure address for an image to HTTPS whenever possible."},"Upgradable script":{"passed":true,"result":"blocked","description":"Checks to see if the browser attempts to upgrade an insecure address for an script to HTTPS whenever possible."},"Upgradable hyperlink":{"upgraded":false,"passed":false,"description":"Checks to see if the user has clicked on a hyperlink to an insecure address, if the browser upgrades that address to HTTPS whenever possible."},"Upgradable address":{"upgraded":false,"passed":false,"description":"Checks to see if an insecure address entered into the browser's address bar is upgraded to HTTPS whenever possible."},"Insecure website warning":{"passed":false,"result":"Insecure website loaded","description":"Checks to see if the browser stops loading an insecure website and warns the user before giving them the option to continue. Known as HTTPS-Only Mode in some browsers."}},"fingerprinting":{"screenX":{"expression":"screenX","actual_value":0,"desired_min":0,"desired_max":10,"passed":true,"description":"Position, in pixels, of the left edge of the browser window on screen.","desired_min_value":0,"desired_max_value":10},"screenY":{"expression":"screenY","actual_value":0,"desired_min":0,"desired_max":10,"passed":true,"description":"Position, in pixels, of the top edge of the browser window on screen.","desired_min_value":0,"desired_max_value":10},"outerHeight":{"expression":"outerHeight","actual_value":561,"desired_min":"innerHeight - 10","desired_max":"innerHeight + 10","passed":false,"description":"Height of the browser window in pixels, including browser chrome.","desired_min_value":1456,"desired_max_value":1476},"screen.width":{"expression":"screen.width","actual_value":375,"desired_min":"innerWidth - 10","desired_max":"innerWidth + 10","passed":false,"description":"Width of the user's screen, in pixels.","desired_min_value":970,"desired_max_value":990},"screen.height":{"expression":"screen.height","actual_value":667,"desired_min":"innerHeight - 10","desired_max":"innerHeight + 10","passed":false,"description":"Height of the user's screen, in pixels.","desired_min_value":1456,"desired_max_value":1476},"Media query screen width":{"name":"Media query screen width","actual_value":375,"desired_min":"innerWidth - 10","desired_max":"innerWidth + 10","passed":false,"description":"Width of the user's screen in pixels.","desired_min_value":970,"desired_max_value":990},"Media query screen height":{"name":"Media query screen height","actual_value":667,"desired_min":"innerHeight - 10","desired_max":"innerHeight + 10","passed":false,"description":"Height of the user's screen in pixels.","desired_min_value":1456,"desired_max_value":1476}},"navigation":{"sessionStorage":{"write":"(secret) => sessionStorage.setItem(\"secret\", secret)","read":"() => sessionStorage.getItem(\"secret\")","unsupported":false,"readSameFirstParty":"fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0","readDifferentFirstParty":null,"passed":true,"testFailed":false,"description":"The sessionStorage API is similar to the localStorage API, but it does not persist across tabs or across browser sessions. Nonetheless, it can be used to track users if they navigate from one website to another. This tracking can be thwarted by partitioning sessionStorage between websites."},"window.name":{"write":"(secret) => window.name = \"name_\" + secret","read":"() => window.name","unsupported":false,"readSameFirstParty":"name_fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0","readDifferentFirstParty":"","passed":true,"testFailed":false,"description":"The window.name API allows websites to store data that will persist after the user has navigated the tab to a different website. This mechanism could be partitioned so that data is not allowed to persist between websites."},"document.referrer":{"write":"(secret) => { /* do nothing */ }","read":"() => document.referrer","unsupported":false,"readSameFirstParty":"https://test-pages.privacytests2.org/","readDifferentFirstParty":"https://test-pages.privacytests2.org/","passed":false,"testFailed":false,"description":"The Referer [sic] request header is a mechanism used by browsers to let a website know where the user is visiting from. This header is inherently tracking users across websites. In recent times, browsers have switched to a policy of trimming a referrer to convey less tracking information, but Referer continues to convey cross-site tracking data by default."}},"supercookies":{"cookie (JS)":{"write":"(secret) => {\n document.cookie = `secret=${secret}_js; max-age=3600; SameSite=None; Secure`;\n }","read":"() => document.cookie ? document.cookie.match(/secret=([\\w-]+)/)[1] : null","unsupported":false,"readSameFirstParty":"fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0_js","readDifferentFirstParty":null,"passed":true,"testFailed":false,"description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them."},"cookie (HTTP)":{"write":"async (secret) => {\n // Request a page that will send an HTTPOnly 'set-cookie' response header with secret value.\n await fetch(`${baseURI}cookie?secret=${secret}_http`);\n }","read":"async () => {\n // Test if we now send a requests with a 'cookie' header containing the secret.\n let response = await fetch(`${baseURI}headers`);\n let cookie = (await response.json())[\"cookie\"];\n return cookie ? cookie.match(/secret=([\\w-]+)/)[1]: null;\n }","unsupported":false,"readSameFirstParty":"fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0_http","readDifferentFirstParty":null,"passed":true,"testFailed":false,"description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them."},"localStorage":{"write":"(secret) => localStorage.setItem(\"secret\", secret)","read":"() => localStorage.getItem(\"secret\")","unsupported":false,"readSameFirstParty":"fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0","readDifferentFirstParty":null,"passed":true,"testFailed":false,"description":"The localStorage API gives websites access to a key-value database that will remain available across visits. If the localStorage API is not partitioned or blocked, it can also be used to track users across websites."},"indexedDB":{"write":"async (secret) => {\n try {\n return await IdbKeyVal.set(\"secret\", secret);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"() => IdbKeyVal.get(\"secret\")","unsupported":false,"readSameFirstParty":"fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0","passed":true,"testFailed":false,"description":"The IndexedDB API exposes a transactional database to web pages. That database can be used to track users across websites, unless it is partitioned."},"SharedWorker":{"write":"async (secret) => {\n try {\n let worker = new SharedWorker(\"supercookies_sharedworker.js\");\n worker.port.start();\n// console.log(\"worker\", worker);\n const messagePromise = new Promise((resolve) => {\n worker.port.onmessage = (e) => resolve(e.data);\n });\n worker.port.postMessage(secret);\n await messagePromise;\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n let worker = new SharedWorker(\"supercookies_sharedworker.js\");\n worker.port.start();\n const messagePromise = new Promise((resolve, reject) => {\n worker.port.onmessage = (e) => resolve(e.data);\n setTimeout(() => reject(new Error(\"no SharedWorker message received\")), 200);\n });\n worker.port.postMessage(\"request\");\n const message = await messagePromise;\n if (message === \"none\") {\n throw new Error(\"Unsupported\");\n }\n return message;\n }","unsupported":true,"readSameFirstParty":"Error: Unsupported","readDifferentFirstParty":"Error: Unsupported","testFailed":false,"description":"The SharedWorker API allows scripts from multiple tabs to share a background thread of computation. If SharedWorker is not partitioned, then it can be abused to shared data between websites in your browser."},"blob":{"write":"(secret) => {\n try {\n let blobURL = URL.createObjectURL(new Blob([secret]));\n fetch(`${baseURI}blob?mode=write&key=${secret}&blobUrl=${encodeURIComponent(blobURL)}`);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async (secret) => {\n let response = await fetch(`${baseURI}blob?mode=read&key=${secret}`);\n let result = await response.json();\n let blobUrl = decodeURIComponent(result.blobUrl);\n let blobResponse = await fetch(blobUrl);\n return blobResponse.text();\n }","unsupported":false,"readSameFirstParty":"Error: Load failed","readDifferentFirstParty":"Error: Load failed","testFailed":true,"description":"A 'blob URL' is a local reference to some raw data. Trackers can use a blob URL to share data between websites."},"BroadcastChannel":{"write":"(secret) => {\n try {\n let bc = new BroadcastChannel(\"secrets\");\n bc.onmessage = (event) => {\n if (event.data === \"request\") {\n bc.postMessage(secret);\n }\n };\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"() =>\n new Promise((resolve, reject) => {\n let bc = new BroadcastChannel(\"secrets\");\n bc.onmessage = (event) => {\n if (event.data !== \"request\") {\n resolve(event.data);\n }\n };\n bc.postMessage(\"request\");\n setTimeout(() => reject({message: \"no BroadcastChannel message\"}), 3000);\n })","unsupported":false,"readSameFirstParty":"Error: no BroadcastChannel message","readDifferentFirstParty":"Error: no BroadcastChannel message","testFailed":true,"description":"A BroadcastChannel is designed to send messages between tabs. In some browsers it can be used for cross-site communication and tracking."},"fetch cache":{"write":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n return key;\n }","read":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n let countResponse = await fetch(testURI(\"ctr\", \"fetch\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","unsupported":false,"readSameFirstParty":"1","readDifferentFirstParty":"2","passed":true,"testFailed":false,"description":"When a resource is received via the Fetch API, it is frequently cached. That cache can potentially be abused for cross-site tracking."},"XMLHttpRequest cache":{"write":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n return key;\n }","read":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n let countResponse = await fetch(testURI(\"ctr\", \"xhr\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","unsupported":false,"readSameFirstParty":"1","readDifferentFirstParty":"2","passed":true,"testFailed":false,"description":"Similar to the newer Fetch API, any resource received may be cached by the browser. The cache is potentially vulnerable to cross-site tracking attack."},"iframe cache":{"write":"(key) => new Promise((resolve, reject) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n iframe.addEventListener(\"load\", () => resolve(key), {once: true});\n iframe.src = testURI(\"resource\", \"page\", key);\n })","read":"async (key) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n let iframeLoadPromise = new Promise((resolve, reject) => {\n iframe.addEventListener(\"load\", resolve, {once: true});\n });\n let address = testURI(\"resource\", \"page\", key);\n iframe.src = address;\n await iframeLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"page\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","unsupported":false,"readSameFirstParty":"1","readDifferentFirstParty":"2","passed":true,"testFailed":false,"description":"An iframe is an element in a web page than allows websites to embed a second web page. Caching of this web page could be abused for cross-site tracking."},"CacheStorage":{"write":"async (key) => {\n try {\n let cache = await caches.open(\"supercookies\");\n cache.addAll([`test.css?key=${key}`]);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n let cache = await caches.open(\"supercookies\");\n let cacheKeys = await cache.keys();\n let url = cacheKeys[0].url;\n return (new URL(url)).searchParams.get(\"key\");\n }","unsupported":false,"readSameFirstParty":"fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0","readDifferentFirstParty":"Error: undefined is not an object (evaluating 'cacheKeys[0].url')","passed":true,"testFailed":false,"description":"The Cache API is a content storage mechanism originally introduced to support ServiceWorkers. If the same Cache object is accessible to multiple websites, it can be abused to track users."},"favicon cache":{"write":"(key) => key","read":"async (key) => {\n // Wait for the favicon to load (defined in supercookies.html)\n await sleepMs(2000);\n let response = await fetch(\n testURI(\"ctr\", \"favicon\", key), {\"cache\": \"reload\"});\n let count = (await response.text()).trim();\n if (count === \"0\") {\n throw new Error(\"No requests received\");\n }\n return count;\n }","unsupported":false,"readSameFirstParty":"1","readDifferentFirstParty":"1","passed":false,"testFailed":false,"description":"A favicon is an icon that represents a website, typically shown in browser tab and bookmarks menu. If the favicon cache is not partitioned, it can be used to track users across websites."},"locks":{"write":"async (key) => {\n if (navigator.locks) {\n navigator.locks.request(key, lock => new Promise((f,r) => {}));\n let queryResult = await navigator.locks.query();\n return queryResult.held[0].clientId;\n } else {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n if (navigator.locks) {\n let queryResult = await navigator.locks.query();\n return queryResult.held[0].name;\n }\n }","unsupported":false,"readSameFirstParty":"Error: undefined is not an object (evaluating 'queryResult.held[0].name')","readDifferentFirstParty":"Error: undefined is not an object (evaluating 'queryResult.held[0].name')","testFailed":true,"description":"navigator.locks (only supported in some browsers) allows scripts on multiple tabs to coordinate. If this API is not partitioned, it can be used for cross-site tracking."},"TLS Session ID":{"write":"async () => {\n let results = await fetch(\"https://tls.privacytests2.org:8900/\");\n return (await results.json()).sessionId;\n }","read":"async () => {\n let results = await fetch(\"https://tls.privacytests2.org:8900/\");\n return (await results.json()).sessionId;\n }","unsupported":false,"readSameFirstParty":"bedc055b9b6bb7bdd21841eb317199ab2ab4354ff285eb13b5c8aa616d42d3b2","readDifferentFirstParty":"f8de1a5f6f0a1ead087583d3698c815793edb17f4fc94ed1127aee3877b6a866","passed":true,"testFailed":false,"description":"The TLS protocol is used by HTTPS to make connections secure. If the browser were to re-use a TLS session, then the session ID could be used to track users across websites."},"H1 connection":{"write":"async (secret) => {\n await fetch(`https://h1.privacytests2.org:8901/?mode=write&secret=${secret}`, {cache: \"no-store\"});\n }","read":"async () => {\n let response = await fetch(`https://h1.privacytests2.org:8901/?mode=read`, {cache: \"no-store\"});\n return await response.text();\n }","unsupported":false,"readSameFirstParty":"fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0","readDifferentFirstParty":"","passed":true,"testFailed":false,"description":"HTTP/1.x are the classic web connection protocols. If these connections are re-used across websites, they can be used to track users."},"H2 connection":{"write":"async (secret) => {\n await fetch(`https://h2.privacytests2.org:8902/?mode=write&secret=${secret}`, {cache: \"no-store\"});\n }","read":"async () => {\n let response = await fetch(`https://h2.privacytests2.org:8902/?mode=read`, {cache: \"no-store\"});\n return await response.text();\n }","unsupported":false,"readSameFirstParty":"fab522bb-62ff-4e6c-8eef-e03c5fbc0eb0","readDifferentFirstParty":"","passed":true,"testFailed":false,"description":"HTTP/2 is a web connection protocol introduced in 2015. Some browsers re-use HTTP/2 connections across websites and can thus be used to track users."},"H3 connection":{"write":"async (secret) => {\n // Ensure that we can switch over to h3 via alt-svc:\n for (let i = 0; i<3; ++i) {\n await fetch(`https://h3.privacytests2.org:4434/connection_id`, {cache: \"no-store\"});\n await sleepMs(500);\n }\n // Are we now connecting over h3?\n let response = await fetch(`https://h3.privacytests2.org:4434/connection_id`, {cache: \"no-store\"});\n let text = await response.text();\n // Empty response text indicates we are not connecting over h3:\n if (text.trim() === \"\") {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n let response = await fetch(`https://h3.privacytests2.org:4434/connection_id`);\n return await response.text();\n }","unsupported":false,"readSameFirstParty":"6d06131f76f6da15e1b870be174e5ea3","readDifferentFirstParty":"f0431e05edc6e81e6f4496205e89fb11","passed":true,"testFailed":false,"description":"HTTP/3 is a new standard HTTP connection protocol, still in draft but widely supported by browsers. If it is not partitioned, it can be used to track users across websites."},"CookieStore":{"write":"(data) => {\n const msPerHour = 60 * 60 * 1000;\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n window.cookieStore.set({\n name: \"partition_test\",\n value: data,\n expires: Date.now() + msPerHour,\n sameSite: \"none\"\n });\n }","read":"async () => {\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n const cookie = await window.cookieStore.get(\"partition_test\");\n if (!cookie) {\n return null;\n }\n return cookie.value;\n }","unsupported":true,"readSameFirstParty":"Error: Unsupported","readDifferentFirstParty":"Error: Unsupported","testFailed":false,"description":"The Cookie Store API is an alternative asynchronous API for managing cookies, supported by some browsers."},"getDirectory":{"write":"async (secret) => {\n try {\n const root = await navigator.storage.getDirectory();\n const fileHandle = await root.getFileHandle(\"secret.txt\", { create: true });\n const stream = await fileHandle.createWritable();\n await stream.write(secret);\n await stream.close();\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n try {\n const root = await navigator.storage.getDirectory();\n const fileHandle = await root.getFileHandle(\"secret.txt\");\n const file = await fileHandle.getFile();\n return file.text();\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","unsupported":true,"readSameFirstParty":"","readDifferentFirstParty":"Error: Unsupported","testFailed":false,"description":"navigator.storage.getDirectory exposes a location for storing files to web content. In some cases, these files may be shared across tabs."},"ServiceWorker":{"write":"async (key) => {\n if (!navigator.serviceWorker) {\n throw new Error(\"Unsupported\");\n }\n let registration = await navigator.serviceWorker.register(\n 'serviceWorker.js');\n console.log(registration);\n await navigator.serviceWorker.ready;\n console.log(\"service worker ready\");\n await sleepMs(100);\n await fetch(`serviceworker-write?secret=${key}`);\n }","read":"async () => {\n console.log(\"trying to register the serviceworker now...\");\n const registration = await Promise.race([\n navigator.serviceWorker.register('serviceWorker.js'),\n sleepMs(500)\n ]);\n if (registration === undefined) {\n // We timed out or otherwise failed.\n throw new Error(\"ServiceWorker registration failed\");\n }\n console.log(registration);\n await navigator.serviceWorker.ready;\n console.log(\"service worker ready\");\n await sleepMs(100);\n let response = await fetch(\"serviceworker-read\");\n return await response.text();\n }","unsupported":false,"readSameFirstParty":"","readDifferentFirstParty":"","testFailed":true,"description":"The ServiceWorker API allows websites to run code in the background and store content in the browser for offline use. If a ServiceWorker can be accessed from multiple websites, it can be abused to track users across sites."},"CSS cache":{"write":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return key;\n }","read":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return fontFamily;\n }","unsupported":false,"readSameFirstParty":"fake_8205556862175178","readDifferentFirstParty":"fake_04326589365858369","passed":true,"testFailed":false,"description":"CSS stylesheets are cached, and if that cache is shared between websites, it can be used to track users across sites."},"font cache":{"write":"async (key) => {\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } body { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n return key;\n }","read":"async (key) => {\n const text = document.createElement(\"span\");\n text.id = \"text\";\n text.innerText = \"test\";\n document.body.appendChild(text);\n const originalWidth = text.getBoundingClientRect().width;\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } #text { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n let newWidth;\n do {\n await sleepMs(100);\n newWidth = text.getBoundingClientRect().width;\n } while (newWidth < 0 || newWidth === originalWidth)\n let response = await fetch(\n testURI(\"ctr\", \"font\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","unsupported":false,"readSameFirstParty":"2","readDifferentFirstParty":"3","passed":true,"testFailed":false,"description":"Web fonts are sometimes stored in their own cache, which is vulnerable to being abused for cross-site tracking."},"image cache":{"write":"(key) => new Promise((resolve, reject) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n img.addEventListener(\"load\", () => resolve(key), {once: true});\n img.src = testURI(\"resource\", \"image\", key);\n })","read":"async (key) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n let imgLoadPromise = new Promise((resolve, reject) => {\n img.addEventListener(\"load\", resolve, {once: true});\n });\n img.src = testURI(\"resource\", \"image\", key);\n await imgLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"image\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","unsupported":false,"readSameFirstParty":"2","readDifferentFirstParty":"3","passed":true,"testFailed":false,"description":"Caching of images in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking."},"script cache":{"write":"(key) => new Promise((resolve, reject) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n script.addEventListener(\"load\", () => resolve(key), {once: true});\n script.src = testURI(\"resource\", \"script\", key);\n })","read":"async (key) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n let scriptLoadPromise = new Promise((resolve, reject) => {\n script.addEventListener(\"load\", resolve, {once: true});\n });\n script.src = testURI(\"resource\", \"script\", key);\n await scriptLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"script\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","unsupported":false,"readSameFirstParty":"2","readDifferentFirstParty":"3","passed":true,"testFailed":false,"description":"Caching of scripts in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking."},"prefetch cache":{"write":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n return key;\n }","read":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n await sleepMs(500);\n let response = await fetch(\n testURI(\"ctr\", \"prefetch\", key), {\"cache\": \"reload\"});\n let countString = (await response.text()).trim();\n if (parseInt(countString) === 0) {\n throw new Error(\"No requests received\");\n }\n return countString;\n }","unsupported":true,"readSameFirstParty":"Error: No requests received","readDifferentFirstParty":"Error: No requests received","testFailed":false,"description":"A suggests to browsers they should fetch a resource ahead of time and cache it. But if browsers don't partition this cache, it can be used to track users across websites."},"Alt-Svc":{"write":"async () => {\n // Clear Alt-Svc caching first.\n let responseText = \"\";\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/clear\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after clear:\", responseText);\n // Store \"h3\" state in Alt-Svc cache\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/set\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after set:\", responseText);\n }","read":"async () => {\n const protocol = await fetchText(altSvcOrigin + \"/protocol\");\n if ((new URL(location)).searchParams.get(\"thirdparty\") === \"same\") {\n if (protocol !== \"h3\") {\n throw new Error(\"Unsupported\");\n }\n }\n return protocol;\n }","unsupported":true,"readSameFirstParty":"Error: Unsupported","readDifferentFirstParty":"h3","testFailed":false,"description":"Alt-Svc allows the server to indicate to the web browser that a resource should be loaded on a different server. Because this is a persistent setting, it could be used to track users across websites if it is not correctly partitioned."},"HSTS cache":{"description":"The HTTP Strict-Transport-Security response header allows a website to signal that it should only be accessed via HTTPS. The browser remembers this directive in a database, but if this database is not partitioned, then it can be used to track users across websites.\"","passed":true,"unsupported":false,"testFailed":false,"readDifferentFirstParty":"Used http","readSameFirstParty":"not tested","write":"set HSTS flag","read":"read HSTS flag"},"HSTS cache (fetch)":{"description":"The HTTP Strict-Transport-Security response header allows a website to signal that it should only be accessed via HTTPS. The browser remembers this directive in a database, but if this database is not partitioned, then it can be used to track users across websites.\"","passed":true,"unsupported":false,"testFailed":false,"readDifferentFirstParty":"Used http","readSameFirstParty":"not tested","write":"set HSTS flag","read":"read HSTS flag"}},"trackers":{"Google (third-party ad pixel)":{"url":"https://www.google.com/pagead/1p-user-list/","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://www.google.com/pagead/1p-user-list/"},"Google Tag Manager":{"url":"https://www.googletagmanager.com/gtag.js?id=GTM-NX4SMZL","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://www.googletagmanager.com/gtag.js?id=GTM-NX4SMZL"},"DoubleClick (Google)":{"url":"https://securepubads.g.doubleclick.net/static/glade.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://securepubads.g.doubleclick.net/static/glade.js"},"Google Analytics":{"url":"https://google-analytics.com/urchin.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://google-analytics.com/urchin.js"},"Facebook tracking":{"url":"https://connect.facebook.net/en_US/fbevents.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://connect.facebook.net/en_US/fbevents.js"},"Amazon adsystem":{"url":"https://s.amazon-adsystem.com/dcm","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://s.amazon-adsystem.com/dcm"},"Scorecard Research Beacon":{"url":"https://sb.scorecardresearch.com/internal-c2/default/cs.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://sb.scorecardresearch.com/internal-c2/default/cs.js"},"New Relic":{"url":"https://js-agent.newrelic.com/nr-1212.min.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://js-agent.newrelic.com/nr-1212.min.js"},"Criteo":{"url":"https://dis.criteo.com/dis/rtb/appnexus/cookiematch.aspx","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://dis.criteo.com/dis/rtb/appnexus/cookiematch.aspx"},"Adobe":{"url":"https://munchkin.marketo.net/munchkin.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://munchkin.marketo.net/munchkin.js"},"Adobe Audience Manager":{"url":"https://dpm.demdex.net/ibs","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://dpm.demdex.net/ibs"},"AppNexus":{"url":"https://ib.adnxs.com/px?id=178248&t=1","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://ib.adnxs.com/px?id=178248&t=1"},"Twitter pixel":{"url":"https://t.co/i/adsct","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://t.co/i/adsct"},"Bing Ads":{"url":"https://bat.bing.com/bat.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://bat.bing.com/bat.js"},"Taboola":{"url":"https://trc.taboola.com/futureplc-tomsguide/trc/3/json","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://trc.taboola.com/futureplc-tomsguide/trc/3/json"},"Index Exchange":{"url":"https://dsum-sec.casalemedia.com/crum?cm_dsp_id=10&external_user_id=629685505537&C=1","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://dsum-sec.casalemedia.com/crum?cm_dsp_id=10&external_user_id=629685505537&C=1"},"Yandex Ads":{"url":"https://yandex.ru/ads/system/header-bidding.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://yandex.ru/ads/system/header-bidding.js"},"Quantcast":{"url":"https://pixel.quantserve.com/pixel","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://pixel.quantserve.com/pixel"},"Chartbeat":{"url":"https://static.chartbeat.com/js/chartbeat.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://static.chartbeat.com/js/chartbeat.js"}}},"timeStarted":"2024-03-31T23:39:18.639Z","reportedVersion":"123.2420.56","os":"Darwin","os_version":"Darwin Kernel Version 23.4.0: Wed Feb 21 21:44:06 PST 2024; root:xnu-10063.101.15~2/RELEASE_ARM64_T8103"},{"browser":"edge","incognito":false,"tor":false,"nightly":false,"testResults":{"session_3p":{"cookie (JS)":{"unsupported":true,"testFailed":false,"write":"(secret) => {\n document.cookie = `secret=${secret}_js; max-age=3600; SameSite=None; Secure`;\n }","read":"() => document.cookie ? document.cookie.match(/secret=([\\w-]+)/)[1] : null","description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them.","readSameSession":null,"readDifferentSession":null},"cookie (HTTP)":{"unsupported":true,"testFailed":false,"write":"async (secret) => {\n // Request a page that will send an HTTPOnly 'set-cookie' response header with secret value.\n await fetch(`${baseURI}cookie?secret=${secret}_http`);\n }","read":"async () => {\n // Test if we now send a requests with a 'cookie' header containing the secret.\n let response = await fetch(`${baseURI}headers`);\n let cookie = (await response.json())[\"cookie\"];\n return cookie ? cookie.match(/secret=([\\w-]+)/)[1]: null;\n }","description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them.","readSameSession":null,"readDifferentSession":null},"localStorage":{"unsupported":false,"passed":true,"testFailed":false,"write":"(secret) => localStorage.setItem(\"secret\", secret)","read":"() => localStorage.getItem(\"secret\")","description":"The localStorage API gives websites access to a key-value database that will remain available across visits. If the localStorage API is not partitioned or blocked, it can also be used to track users across websites.","readSameSession":"8e954de4-8067-47e9-a148-bd3b15d35eb2_3p","readDifferentSession":null},"indexedDB":{"unsupported":false,"passed":true,"testFailed":false,"write":"async (secret) => {\n try {\n return await IdbKeyVal.set(\"secret\", secret);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"() => IdbKeyVal.get(\"secret\")","description":"The IndexedDB API exposes a transactional database to web pages. That database can be used to track users across websites, unless it is partitioned.","readSameSession":"8e954de4-8067-47e9-a148-bd3b15d35eb2_3p"},"fetch cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n return key;\n }","read":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n let countResponse = await fetch(testURI(\"ctr\", \"fetch\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","description":"When a resource is received via the Fetch API, it is frequently cached. That cache can potentially be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"XMLHttpRequest cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n return key;\n }","read":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n let countResponse = await fetch(testURI(\"ctr\", \"xhr\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","description":"Similar to the newer Fetch API, any resource received may be cached by the browser. The cache is potentially vulnerable to cross-site tracking attack.","readSameSession":"1","readDifferentSession":"1"},"iframe cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n iframe.addEventListener(\"load\", () => resolve(key), {once: true});\n iframe.src = testURI(\"resource\", \"page\", key);\n })","read":"async (key) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n let iframeLoadPromise = new Promise((resolve, reject) => {\n iframe.addEventListener(\"load\", resolve, {once: true});\n });\n let address = testURI(\"resource\", \"page\", key);\n iframe.src = address;\n await iframeLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"page\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"An iframe is an element in a web page than allows websites to embed a second web page. Caching of this web page could be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"CacheStorage":{"unsupported":false,"passed":true,"testFailed":false,"write":"async (key) => {\n try {\n let cache = await caches.open(\"supercookies\");\n cache.addAll([`test.css?key=${key}`]);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n let cache = await caches.open(\"supercookies\");\n let cacheKeys = await cache.keys();\n let url = cacheKeys[0].url;\n return (new URL(url)).searchParams.get(\"key\");\n }","description":"The Cache API is a content storage mechanism originally introduced to support ServiceWorkers. If the same Cache object is accessible to multiple websites, it can be abused to track users.","readSameSession":"8e954de4-8067-47e9-a148-bd3b15d35eb2_3p","readDifferentSession":"Error: undefined is not an object (evaluating 'cacheKeys[0].url')"},"favicon cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => key","read":"async (key) => {\n // Wait for the favicon to load (defined in supercookies.html)\n await sleepMs(2000);\n let response = await fetch(\n testURI(\"ctr\", \"favicon\", key), {\"cache\": \"reload\"});\n let count = (await response.text()).trim();\n if (count === \"0\") {\n throw new Error(\"No requests received\");\n }\n return count;\n }","description":"A favicon is an icon that represents a website, typically shown in browser tab and bookmarks menu. If the favicon cache is not partitioned, it can be used to track users across websites.","readSameSession":"1","readDifferentSession":"1"},"CookieStore":{"unsupported":true,"testFailed":false,"write":"(data) => {\n const msPerHour = 60 * 60 * 1000;\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n window.cookieStore.set({\n name: \"partition_test\",\n value: data,\n expires: Date.now() + msPerHour,\n sameSite: \"none\"\n });\n }","read":"async () => {\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n const cookie = await window.cookieStore.get(\"partition_test\");\n if (!cookie) {\n return null;\n }\n return cookie.value;\n }","description":"The Cookie Store API is an alternative asynchronous API for managing cookies, supported by some browsers.","readSameSession":"Error: Unsupported","readDifferentSession":"Error: Unsupported"},"CSS cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return key;\n }","read":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return fontFamily;\n }","description":"CSS stylesheets are cached, and if that cache is shared between websites, it can be used to track users across sites.","readSameSession":"fake_2563349718763097","readDifferentSession":"fake_2563349718763097"},"image cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n img.addEventListener(\"load\", () => resolve(key), {once: true});\n img.src = testURI(\"resource\", \"image\", key);\n })","read":"async (key) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n let imgLoadPromise = new Promise((resolve, reject) => {\n img.addEventListener(\"load\", resolve, {once: true});\n });\n img.src = testURI(\"resource\", \"image\", key);\n await imgLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"image\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Caching of images in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"script cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n script.addEventListener(\"load\", () => resolve(key), {once: true});\n script.src = testURI(\"resource\", \"script\", key);\n })","read":"async (key) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n let scriptLoadPromise = new Promise((resolve, reject) => {\n script.addEventListener(\"load\", resolve, {once: true});\n });\n script.src = testURI(\"resource\", \"script\", key);\n await scriptLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"script\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Caching of scripts in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"font cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } body { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n return key;\n }","read":"async (key) => {\n const text = document.createElement(\"span\");\n text.id = \"text\";\n text.innerText = \"test\";\n document.body.appendChild(text);\n const originalWidth = text.getBoundingClientRect().width;\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } #text { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n let newWidth;\n do {\n await sleepMs(100);\n newWidth = text.getBoundingClientRect().width;\n } while (newWidth < 0 || newWidth === originalWidth)\n let response = await fetch(\n testURI(\"ctr\", \"font\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Web fonts are sometimes stored in their own cache, which is vulnerable to being abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"prefetch cache":{"unsupported":true,"testFailed":false,"write":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n return key;\n }","read":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n await sleepMs(500);\n let response = await fetch(\n testURI(\"ctr\", \"prefetch\", key), {\"cache\": \"reload\"});\n let countString = (await response.text()).trim();\n if (parseInt(countString) === 0) {\n throw new Error(\"No requests received\");\n }\n return countString;\n }","description":"A suggests to browsers they should fetch a resource ahead of time and cache it. But if browsers don't partition this cache, it can be used to track users across websites.","readSameSession":"Error: No requests received","readDifferentSession":"Error: No requests received"},"Alt-Svc":{"unsupported":true,"testFailed":false,"write":"async () => {\n // Clear Alt-Svc caching first.\n let responseText = \"\";\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/clear\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after clear:\", responseText);\n // Store \"h3\" state in Alt-Svc cache\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/set\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after set:\", responseText);\n }","read":"async () => {\n const protocol = await fetchText(altSvcOrigin + \"/protocol\");\n if ((new URL(location)).searchParams.get(\"thirdparty\") === \"same\") {\n if (protocol !== \"h3\") {\n throw new Error(\"Unsupported\");\n }\n }\n return protocol;\n }","description":"Alt-Svc allows the server to indicate to the web browser that a resource should be loaded on a different server. Because this is a persistent setting, it could be used to track users across websites if it is not correctly partitioned.","readSameSession":"h2","readDifferentSession":"h3"}},"session_1p":{"cookie (JS)":{"unsupported":false,"passed":false,"testFailed":false,"write":"(secret) => {\n document.cookie = `secret=${secret}_js; max-age=3600; SameSite=None; Secure`;\n }","read":"() => document.cookie ? document.cookie.match(/secret=([\\w-]+)/)[1] : null","description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them.","readSameSession":"8e954de4-8067-47e9-a148-bd3b15d35eb2_1p_js","readDifferentSession":"8e954de4-8067-47e9-a148-bd3b15d35eb2_1p_js"},"cookie (HTTP)":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (secret) => {\n // Request a page that will send an HTTPOnly 'set-cookie' response header with secret value.\n await fetch(`${baseURI}cookie?secret=${secret}_http`);\n }","read":"async () => {\n // Test if we now send a requests with a 'cookie' header containing the secret.\n let response = await fetch(`${baseURI}headers`);\n let cookie = (await response.json())[\"cookie\"];\n return cookie ? cookie.match(/secret=([\\w-]+)/)[1]: null;\n }","description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them.","readSameSession":"8e954de4-8067-47e9-a148-bd3b15d35eb2_1p_http","readDifferentSession":"8e954de4-8067-47e9-a148-bd3b15d35eb2_1p_http"},"localStorage":{"unsupported":false,"passed":false,"testFailed":false,"write":"(secret) => localStorage.setItem(\"secret\", secret)","read":"() => localStorage.getItem(\"secret\")","description":"The localStorage API gives websites access to a key-value database that will remain available across visits. If the localStorage API is not partitioned or blocked, it can also be used to track users across websites.","readSameSession":"8e954de4-8067-47e9-a148-bd3b15d35eb2_1p","readDifferentSession":"8e954de4-8067-47e9-a148-bd3b15d35eb2_1p"},"indexedDB":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (secret) => {\n try {\n return await IdbKeyVal.set(\"secret\", secret);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"() => IdbKeyVal.get(\"secret\")","description":"The IndexedDB API exposes a transactional database to web pages. That database can be used to track users across websites, unless it is partitioned.","readSameSession":"8e954de4-8067-47e9-a148-bd3b15d35eb2_1p","readDifferentSession":"8e954de4-8067-47e9-a148-bd3b15d35eb2_1p"},"fetch cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n return key;\n }","read":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n let countResponse = await fetch(testURI(\"ctr\", \"fetch\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","description":"When a resource is received via the Fetch API, it is frequently cached. That cache can potentially be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"XMLHttpRequest cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n return key;\n }","read":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n let countResponse = await fetch(testURI(\"ctr\", \"xhr\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","description":"Similar to the newer Fetch API, any resource received may be cached by the browser. The cache is potentially vulnerable to cross-site tracking attack.","readSameSession":"1","readDifferentSession":"1"},"iframe cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n iframe.addEventListener(\"load\", () => resolve(key), {once: true});\n iframe.src = testURI(\"resource\", \"page\", key);\n })","read":"async (key) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n let iframeLoadPromise = new Promise((resolve, reject) => {\n iframe.addEventListener(\"load\", resolve, {once: true});\n });\n let address = testURI(\"resource\", \"page\", key);\n iframe.src = address;\n await iframeLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"page\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"An iframe is an element in a web page than allows websites to embed a second web page. Caching of this web page could be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"CacheStorage":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n try {\n let cache = await caches.open(\"supercookies\");\n cache.addAll([`test.css?key=${key}`]);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n let cache = await caches.open(\"supercookies\");\n let cacheKeys = await cache.keys();\n let url = cacheKeys[0].url;\n return (new URL(url)).searchParams.get(\"key\");\n }","description":"The Cache API is a content storage mechanism originally introduced to support ServiceWorkers. If the same Cache object is accessible to multiple websites, it can be abused to track users.","readSameSession":"18747aa0-a493-4b2f-8684-a70dc7fadf6a_1p","readDifferentSession":"18747aa0-a493-4b2f-8684-a70dc7fadf6a_1p"},"favicon cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => key","read":"async (key) => {\n // Wait for the favicon to load (defined in supercookies.html)\n await sleepMs(2000);\n let response = await fetch(\n testURI(\"ctr\", \"favicon\", key), {\"cache\": \"reload\"});\n let count = (await response.text()).trim();\n if (count === \"0\") {\n throw new Error(\"No requests received\");\n }\n return count;\n }","description":"A favicon is an icon that represents a website, typically shown in browser tab and bookmarks menu. If the favicon cache is not partitioned, it can be used to track users across websites.","readSameSession":"1","readDifferentSession":"1"},"CookieStore":{"unsupported":true,"testFailed":false,"write":"(data) => {\n const msPerHour = 60 * 60 * 1000;\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n window.cookieStore.set({\n name: \"partition_test\",\n value: data,\n expires: Date.now() + msPerHour,\n sameSite: \"none\"\n });\n }","read":"async () => {\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n const cookie = await window.cookieStore.get(\"partition_test\");\n if (!cookie) {\n return null;\n }\n return cookie.value;\n }","description":"The Cookie Store API is an alternative asynchronous API for managing cookies, supported by some browsers.","readSameSession":"Error: Unsupported","readDifferentSession":"Error: Unsupported"},"CSS cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return key;\n }","read":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return fontFamily;\n }","description":"CSS stylesheets are cached, and if that cache is shared between websites, it can be used to track users across sites.","readSameSession":"fake_17195563322684082","readDifferentSession":"fake_17195563322684082"},"image cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n img.addEventListener(\"load\", () => resolve(key), {once: true});\n img.src = testURI(\"resource\", \"image\", key);\n })","read":"async (key) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n let imgLoadPromise = new Promise((resolve, reject) => {\n img.addEventListener(\"load\", resolve, {once: true});\n });\n img.src = testURI(\"resource\", \"image\", key);\n await imgLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"image\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Caching of images in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"script cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n script.addEventListener(\"load\", () => resolve(key), {once: true});\n script.src = testURI(\"resource\", \"script\", key);\n })","read":"async (key) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n let scriptLoadPromise = new Promise((resolve, reject) => {\n script.addEventListener(\"load\", resolve, {once: true});\n });\n script.src = testURI(\"resource\", \"script\", key);\n await scriptLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"script\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Caching of scripts in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"font cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } body { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n return key;\n }","read":"async (key) => {\n const text = document.createElement(\"span\");\n text.id = \"text\";\n text.innerText = \"test\";\n document.body.appendChild(text);\n const originalWidth = text.getBoundingClientRect().width;\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } #text { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n let newWidth;\n do {\n await sleepMs(100);\n newWidth = text.getBoundingClientRect().width;\n } while (newWidth < 0 || newWidth === originalWidth)\n let response = await fetch(\n testURI(\"ctr\", \"font\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Web fonts are sometimes stored in their own cache, which is vulnerable to being abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"prefetch cache":{"unsupported":true,"testFailed":false,"write":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n return key;\n }","read":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n await sleepMs(500);\n let response = await fetch(\n testURI(\"ctr\", \"prefetch\", key), {\"cache\": \"reload\"});\n let countString = (await response.text()).trim();\n if (parseInt(countString) === 0) {\n throw new Error(\"No requests received\");\n }\n return countString;\n }","description":"A suggests to browsers they should fetch a resource ahead of time and cache it. But if browsers don't partition this cache, it can be used to track users across websites.","readSameSession":"Error: No requests received","readDifferentSession":"Error: No requests received"},"Alt-Svc":{"unsupported":false,"passed":true,"testFailed":false,"write":"async () => {\n // Clear Alt-Svc caching first.\n let responseText = \"\";\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/clear\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after clear:\", responseText);\n // Store \"h3\" state in Alt-Svc cache\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/set\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after set:\", responseText);\n }","read":"async () => {\n const protocol = await fetchText(altSvcOrigin + \"/protocol\");\n if ((new URL(location)).searchParams.get(\"thirdparty\") === \"same\") {\n if (protocol !== \"h3\") {\n throw new Error(\"Unsupported\");\n }\n }\n return protocol;\n }","description":"Alt-Svc allows the server to indicate to the web browser that a resource should be loaded on a different server. Because this is a persistent setting, it could be used to track users across websites if it is not correctly partitioned.","readSameSession":"h3","readDifferentSession":"h2"}},"misc":{"Tor enabled":{"IsTorExit":false,"passed":false,"description":"The Tor network sends the browser's web requests through a series of relays to hide a user's IP address, thereby helping to mask their identity and location. This test checks to see if the Tor network is being used by default."},"GPC enabled third-party":{"passed":false,"description":"The Global Privacy Control is an HTTP header that can be sent by a browser to instruct a visited website not to sell the user's personal data to other parties. This test checks to see if the GPC header is sent to third-party elements on the web page."},"ECH enabled":{"SNI_status":"plaintext","passed":false,"description":"Encrypted Client Hello (ECH) is a new protocol that hides the website you are visiting from third-party network eavesdroppers."},"Stream isolation":{"write":"() => {\n if (!usingTor) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n if (usingTor) {\n return ipAddress;\n } else {\n throw new Error(\"Unsupported\");\n }\n }","unsupported":true,"readSameFirstParty":"Error: Unsupported","readDifferentFirstParty":"Error: Unsupported","testFailed":false,"description":"Browsers that use Tor can use a different Tor circuit per top-level website."},"IP address leak":{"description":"IP addresses can be used to uniquely identify a large percentage of users. A proxy, VPN, or Tor can mask a user's IP address.","passed":false},"GPC enabled first-party":{"header value":"undefined","description":"The Global Privacy Control is an HTTP header that can be sent by a browser to instruct a website not to sell the user's personal data to third parties. This test checks to see if the GPC header is sent by default to the top-level website.","passed":false}},"query":{"fbclid":{"value":"534245130707274","passed":false,"description":"Facebook Click Identifier"},"gclid":{"value":"534245130707274","passed":false,"description":"Google Click Identifier"},"msclkid":{"value":"534245130707274","passed":false,"description":"Microsoft Click ID"},"mc_eid":{"value":"534245130707274","passed":false,"description":"Mailchimp Email ID (email recipient's address)"},"dclid":{"value":"534245130707274","passed":false,"description":"DoubleClick Click ID (Google)"},"oly_anon_id":{"value":"534245130707274","passed":false,"description":"Omeda marketing 'anonymous' customer id"},"oly_enc_id":{"value":"534245130707274","passed":false,"description":"Omeda marketing 'known' customer id"},"_openstat":{"value":"534245130707274","passed":false,"description":"Yandex tracking parameter"},"vero_conv":{"value":"534245130707274","passed":false,"description":"Vero tracking parameter"},"vero_id":{"value":"534245130707274","passed":false,"description":"Vero tracking parameter"},"wickedid":{"value":"534245130707274","passed":false,"description":"Wicked Reports e-commerce tracking"},"yclid":{"value":"534245130707274","passed":false,"description":"Yandex Click ID"},"__s":{"value":"534245130707274","passed":false,"description":"Drip.com email address tracking parameter"},"rb_clickid":{"value":"534245130707274","passed":false,"description":"Unknown high-entropy tracking parameter"},"s_cid":{"value":"534245130707274","passed":false,"description":"Adobe Site Catalyst tracking parameter"},"ml_subscriber":{"value":"534245130707274","passed":false,"description":"MailerLite email tracking"},"ml_subscriber_hash":{"value":"534245130707274","passed":false,"description":"MailerLite email tracking"},"_hsenc":{"value":"534245130707274","passed":false,"description":"HubSpot tracking parameter"},"__hssc":{"value":"534245130707274","passed":false,"description":"HubSpot tracking parameter"},"__hstc":{"value":"534245130707274","passed":false,"description":"HubSpot tracking parameter"},"__hsfp":{"value":"534245130707274","passed":false,"description":"HubSpot tracking parameter"},"hsCtaTracking":{"value":"534245130707274","passed":false,"description":"HubSpot tracking parameter"},"mkt_tok":{"value":"534245130707274","passed":false,"description":"Adobe Marketo tracking parameter"}},"https":{"Upgradable image":{"passed":true,"result":"upgraded","description":"Checks to see if the browser attempts to upgrade an insecure address for an image to HTTPS whenever possible."},"Upgradable script":{"passed":true,"result":"blocked","description":"Checks to see if the browser attempts to upgrade an insecure address for an script to HTTPS whenever possible."},"Upgradable hyperlink":{"upgraded":false,"passed":false,"description":"Checks to see if the user has clicked on a hyperlink to an insecure address, if the browser upgrades that address to HTTPS whenever possible."},"Upgradable address":{"upgraded":false,"passed":false,"description":"Checks to see if an insecure address entered into the browser's address bar is upgraded to HTTPS whenever possible."},"Insecure website warning":{"passed":false,"result":"Insecure website loaded","description":"Checks to see if the browser stops loading an insecure website and warns the user before giving them the option to continue. Known as HTTPS-Only Mode in some browsers."}},"fingerprinting":{"screenX":{"expression":"screenX","actual_value":0,"desired_min":0,"desired_max":10,"passed":true,"description":"Position, in pixels, of the left edge of the browser window on screen.","desired_min_value":0,"desired_max_value":10},"screenY":{"expression":"screenY","actual_value":0,"desired_min":0,"desired_max":10,"passed":true,"description":"Position, in pixels, of the top edge of the browser window on screen.","desired_min_value":0,"desired_max_value":10},"outerHeight":{"expression":"outerHeight","actual_value":561,"desired_min":"innerHeight - 10","desired_max":"innerHeight + 10","passed":false,"description":"Height of the browser window in pixels, including browser chrome.","desired_min_value":1456,"desired_max_value":1476},"screen.width":{"expression":"screen.width","actual_value":375,"desired_min":"innerWidth - 10","desired_max":"innerWidth + 10","passed":false,"description":"Width of the user's screen, in pixels.","desired_min_value":970,"desired_max_value":990},"screen.height":{"expression":"screen.height","actual_value":667,"desired_min":"innerHeight - 10","desired_max":"innerHeight + 10","passed":false,"description":"Height of the user's screen, in pixels.","desired_min_value":1456,"desired_max_value":1476},"Media query screen width":{"name":"Media query screen width","actual_value":375,"desired_min":"innerWidth - 10","desired_max":"innerWidth + 10","passed":false,"description":"Width of the user's screen in pixels.","desired_min_value":970,"desired_max_value":990},"Media query screen height":{"name":"Media query screen height","actual_value":667,"desired_min":"innerHeight - 10","desired_max":"innerHeight + 10","passed":false,"description":"Height of the user's screen in pixels.","desired_min_value":1456,"desired_max_value":1476}},"navigation":{"sessionStorage":{"write":"(secret) => sessionStorage.setItem(\"secret\", secret)","read":"() => sessionStorage.getItem(\"secret\")","unsupported":false,"readSameFirstParty":"8e954de4-8067-47e9-a148-bd3b15d35eb2","readDifferentFirstParty":null,"passed":true,"testFailed":false,"description":"The sessionStorage API is similar to the localStorage API, but it does not persist across tabs or across browser sessions. Nonetheless, it can be used to track users if they navigate from one website to another. This tracking can be thwarted by partitioning sessionStorage between websites."},"window.name":{"write":"(secret) => window.name = \"name_\" + secret","read":"() => window.name","unsupported":false,"readSameFirstParty":"name_8e954de4-8067-47e9-a148-bd3b15d35eb2","readDifferentFirstParty":"","passed":true,"testFailed":false,"description":"The window.name API allows websites to store data that will persist after the user has navigated the tab to a different website. This mechanism could be partitioned so that data is not allowed to persist between websites."},"document.referrer":{"write":"(secret) => { /* do nothing */ }","read":"() => document.referrer","unsupported":false,"readSameFirstParty":"https://test-pages.privacytests2.org/","readDifferentFirstParty":"https://test-pages.privacytests2.org/","passed":false,"testFailed":false,"description":"The Referer [sic] request header is a mechanism used by browsers to let a website know where the user is visiting from. This header is inherently tracking users across websites. In recent times, browsers have switched to a policy of trimming a referrer to convey less tracking information, but Referer continues to convey cross-site tracking data by default."}},"supercookies":{"cookie (JS)":{"write":"(secret) => {\n document.cookie = `secret=${secret}_js; max-age=3600; SameSite=None; Secure`;\n }","read":"() => document.cookie ? document.cookie.match(/secret=([\\w-]+)/)[1] : null","unsupported":false,"readSameFirstParty":"8e954de4-8067-47e9-a148-bd3b15d35eb2_js","readDifferentFirstParty":null,"passed":true,"testFailed":false,"description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them."},"cookie (HTTP)":{"write":"async (secret) => {\n // Request a page that will send an HTTPOnly 'set-cookie' response header with secret value.\n await fetch(`${baseURI}cookie?secret=${secret}_http`);\n }","read":"async () => {\n // Test if we now send a requests with a 'cookie' header containing the secret.\n let response = await fetch(`${baseURI}headers`);\n let cookie = (await response.json())[\"cookie\"];\n return cookie ? cookie.match(/secret=([\\w-]+)/)[1]: null;\n }","unsupported":false,"readSameFirstParty":"8e954de4-8067-47e9-a148-bd3b15d35eb2_http","readDifferentFirstParty":null,"passed":true,"testFailed":false,"description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them."},"localStorage":{"write":"(secret) => localStorage.setItem(\"secret\", secret)","read":"() => localStorage.getItem(\"secret\")","unsupported":false,"readSameFirstParty":"8e954de4-8067-47e9-a148-bd3b15d35eb2","readDifferentFirstParty":null,"passed":true,"testFailed":false,"description":"The localStorage API gives websites access to a key-value database that will remain available across visits. If the localStorage API is not partitioned or blocked, it can also be used to track users across websites."},"indexedDB":{"write":"async (secret) => {\n try {\n return await IdbKeyVal.set(\"secret\", secret);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"() => IdbKeyVal.get(\"secret\")","unsupported":false,"readSameFirstParty":"8e954de4-8067-47e9-a148-bd3b15d35eb2","passed":true,"testFailed":false,"description":"The IndexedDB API exposes a transactional database to web pages. That database can be used to track users across websites, unless it is partitioned."},"SharedWorker":{"write":"async (secret) => {\n try {\n let worker = new SharedWorker(\"supercookies_sharedworker.js\");\n worker.port.start();\n// console.log(\"worker\", worker);\n const messagePromise = new Promise((resolve) => {\n worker.port.onmessage = (e) => resolve(e.data);\n });\n worker.port.postMessage(secret);\n await messagePromise;\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n let worker = new SharedWorker(\"supercookies_sharedworker.js\");\n worker.port.start();\n const messagePromise = new Promise((resolve, reject) => {\n worker.port.onmessage = (e) => resolve(e.data);\n setTimeout(() => reject(new Error(\"no SharedWorker message received\")), 200);\n });\n worker.port.postMessage(\"request\");\n const message = await messagePromise;\n if (message === \"none\") {\n throw new Error(\"Unsupported\");\n }\n return message;\n }","unsupported":true,"readSameFirstParty":"Error: Unsupported","readDifferentFirstParty":"Error: Unsupported","testFailed":false,"description":"The SharedWorker API allows scripts from multiple tabs to share a background thread of computation. If SharedWorker is not partitioned, then it can be abused to shared data between websites in your browser."},"blob":{"write":"(secret) => {\n try {\n let blobURL = URL.createObjectURL(new Blob([secret]));\n fetch(`${baseURI}blob?mode=write&key=${secret}&blobUrl=${encodeURIComponent(blobURL)}`);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async (secret) => {\n let response = await fetch(`${baseURI}blob?mode=read&key=${secret}`);\n let result = await response.json();\n let blobUrl = decodeURIComponent(result.blobUrl);\n let blobResponse = await fetch(blobUrl);\n return blobResponse.text();\n }","unsupported":false,"readSameFirstParty":"Error: Load failed","readDifferentFirstParty":"Error: Load failed","testFailed":true,"description":"A 'blob URL' is a local reference to some raw data. Trackers can use a blob URL to share data between websites."},"BroadcastChannel":{"write":"(secret) => {\n try {\n let bc = new BroadcastChannel(\"secrets\");\n bc.onmessage = (event) => {\n if (event.data === \"request\") {\n bc.postMessage(secret);\n }\n };\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"() =>\n new Promise((resolve, reject) => {\n let bc = new BroadcastChannel(\"secrets\");\n bc.onmessage = (event) => {\n if (event.data !== \"request\") {\n resolve(event.data);\n }\n };\n bc.postMessage(\"request\");\n setTimeout(() => reject({message: \"no BroadcastChannel message\"}), 3000);\n })","unsupported":false,"readSameFirstParty":"Error: no BroadcastChannel message","readDifferentFirstParty":"Error: no BroadcastChannel message","testFailed":true,"description":"A BroadcastChannel is designed to send messages between tabs. In some browsers it can be used for cross-site communication and tracking."},"fetch cache":{"write":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n return key;\n }","read":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n let countResponse = await fetch(testURI(\"ctr\", \"fetch\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","unsupported":false,"readSameFirstParty":"1","readDifferentFirstParty":"2","passed":true,"testFailed":false,"description":"When a resource is received via the Fetch API, it is frequently cached. That cache can potentially be abused for cross-site tracking."},"XMLHttpRequest cache":{"write":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n return key;\n }","read":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n let countResponse = await fetch(testURI(\"ctr\", \"xhr\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","unsupported":false,"readSameFirstParty":"1","readDifferentFirstParty":"2","passed":true,"testFailed":false,"description":"Similar to the newer Fetch API, any resource received may be cached by the browser. The cache is potentially vulnerable to cross-site tracking attack."},"iframe cache":{"write":"(key) => new Promise((resolve, reject) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n iframe.addEventListener(\"load\", () => resolve(key), {once: true});\n iframe.src = testURI(\"resource\", \"page\", key);\n })","read":"async (key) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n let iframeLoadPromise = new Promise((resolve, reject) => {\n iframe.addEventListener(\"load\", resolve, {once: true});\n });\n let address = testURI(\"resource\", \"page\", key);\n iframe.src = address;\n await iframeLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"page\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","unsupported":false,"readSameFirstParty":"1","readDifferentFirstParty":"2","passed":true,"testFailed":false,"description":"An iframe is an element in a web page than allows websites to embed a second web page. Caching of this web page could be abused for cross-site tracking."},"CacheStorage":{"write":"async (key) => {\n try {\n let cache = await caches.open(\"supercookies\");\n cache.addAll([`test.css?key=${key}`]);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n let cache = await caches.open(\"supercookies\");\n let cacheKeys = await cache.keys();\n let url = cacheKeys[0].url;\n return (new URL(url)).searchParams.get(\"key\");\n }","unsupported":false,"readSameFirstParty":"8e954de4-8067-47e9-a148-bd3b15d35eb2","readDifferentFirstParty":"Error: undefined is not an object (evaluating 'cacheKeys[0].url')","passed":true,"testFailed":false,"description":"The Cache API is a content storage mechanism originally introduced to support ServiceWorkers. If the same Cache object is accessible to multiple websites, it can be abused to track users."},"favicon cache":{"write":"(key) => key","read":"async (key) => {\n // Wait for the favicon to load (defined in supercookies.html)\n await sleepMs(2000);\n let response = await fetch(\n testURI(\"ctr\", \"favicon\", key), {\"cache\": \"reload\"});\n let count = (await response.text()).trim();\n if (count === \"0\") {\n throw new Error(\"No requests received\");\n }\n return count;\n }","unsupported":false,"readSameFirstParty":"1","readDifferentFirstParty":"1","passed":false,"testFailed":false,"description":"A favicon is an icon that represents a website, typically shown in browser tab and bookmarks menu. If the favicon cache is not partitioned, it can be used to track users across websites."},"locks":{"write":"async (key) => {\n if (navigator.locks) {\n navigator.locks.request(key, lock => new Promise((f,r) => {}));\n let queryResult = await navigator.locks.query();\n return queryResult.held[0].clientId;\n } else {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n if (navigator.locks) {\n let queryResult = await navigator.locks.query();\n return queryResult.held[0].name;\n }\n }","unsupported":false,"readSameFirstParty":"Error: undefined is not an object (evaluating 'queryResult.held[0].name')","readDifferentFirstParty":"Error: undefined is not an object (evaluating 'queryResult.held[0].name')","testFailed":true,"description":"navigator.locks (only supported in some browsers) allows scripts on multiple tabs to coordinate. If this API is not partitioned, it can be used for cross-site tracking."},"TLS Session ID":{"write":"async () => {\n let results = await fetch(\"https://tls.privacytests2.org:8900/\");\n return (await results.json()).sessionId;\n }","read":"async () => {\n let results = await fetch(\"https://tls.privacytests2.org:8900/\");\n return (await results.json()).sessionId;\n }","unsupported":false,"readSameFirstParty":"6f033d937b7df3f1487190a531bb16f9a0185428ecae760b87c6e8472db26659","readDifferentFirstParty":"079f6b80ad80403e7ba352dd0e0efaf599717efc4b28b335ab8b1ab892092640","passed":true,"testFailed":false,"description":"The TLS protocol is used by HTTPS to make connections secure. If the browser were to re-use a TLS session, then the session ID could be used to track users across websites."},"H1 connection":{"write":"async (secret) => {\n await fetch(`https://h1.privacytests2.org:8901/?mode=write&secret=${secret}`, {cache: \"no-store\"});\n }","read":"async () => {\n let response = await fetch(`https://h1.privacytests2.org:8901/?mode=read`, {cache: \"no-store\"});\n return await response.text();\n }","unsupported":false,"readSameFirstParty":"8e954de4-8067-47e9-a148-bd3b15d35eb2","readDifferentFirstParty":"","passed":true,"testFailed":false,"description":"HTTP/1.x are the classic web connection protocols. If these connections are re-used across websites, they can be used to track users."},"H2 connection":{"write":"async (secret) => {\n await fetch(`https://h2.privacytests2.org:8902/?mode=write&secret=${secret}`, {cache: \"no-store\"});\n }","read":"async () => {\n let response = await fetch(`https://h2.privacytests2.org:8902/?mode=read`, {cache: \"no-store\"});\n return await response.text();\n }","unsupported":false,"readSameFirstParty":"8e954de4-8067-47e9-a148-bd3b15d35eb2","readDifferentFirstParty":"","passed":true,"testFailed":false,"description":"HTTP/2 is a web connection protocol introduced in 2015. Some browsers re-use HTTP/2 connections across websites and can thus be used to track users."},"H3 connection":{"write":"async (secret) => {\n // Ensure that we can switch over to h3 via alt-svc:\n for (let i = 0; i<3; ++i) {\n await fetch(`https://h3.privacytests2.org:4434/connection_id`, {cache: \"no-store\"});\n await sleepMs(500);\n }\n // Are we now connecting over h3?\n let response = await fetch(`https://h3.privacytests2.org:4434/connection_id`, {cache: \"no-store\"});\n let text = await response.text();\n // Empty response text indicates we are not connecting over h3:\n if (text.trim() === \"\") {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n let response = await fetch(`https://h3.privacytests2.org:4434/connection_id`);\n return await response.text();\n }","unsupported":false,"readSameFirstParty":"339345f0df8eba0416ec8e1d14910f77","readDifferentFirstParty":"ab1667dcef8e86fadbb8c544de58edb8","passed":true,"testFailed":false,"description":"HTTP/3 is a new standard HTTP connection protocol, still in draft but widely supported by browsers. If it is not partitioned, it can be used to track users across websites."},"CookieStore":{"write":"(data) => {\n const msPerHour = 60 * 60 * 1000;\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n window.cookieStore.set({\n name: \"partition_test\",\n value: data,\n expires: Date.now() + msPerHour,\n sameSite: \"none\"\n });\n }","read":"async () => {\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n const cookie = await window.cookieStore.get(\"partition_test\");\n if (!cookie) {\n return null;\n }\n return cookie.value;\n }","unsupported":true,"readSameFirstParty":"Error: Unsupported","readDifferentFirstParty":"Error: Unsupported","testFailed":false,"description":"The Cookie Store API is an alternative asynchronous API for managing cookies, supported by some browsers."},"getDirectory":{"write":"async (secret) => {\n try {\n const root = await navigator.storage.getDirectory();\n const fileHandle = await root.getFileHandle(\"secret.txt\", { create: true });\n const stream = await fileHandle.createWritable();\n await stream.write(secret);\n await stream.close();\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n try {\n const root = await navigator.storage.getDirectory();\n const fileHandle = await root.getFileHandle(\"secret.txt\");\n const file = await fileHandle.getFile();\n return file.text();\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","unsupported":true,"readSameFirstParty":"","readDifferentFirstParty":"Error: Unsupported","testFailed":false,"description":"navigator.storage.getDirectory exposes a location for storing files to web content. In some cases, these files may be shared across tabs."},"ServiceWorker":{"write":"async (key) => {\n if (!navigator.serviceWorker) {\n throw new Error(\"Unsupported\");\n }\n let registration = await navigator.serviceWorker.register(\n 'serviceWorker.js');\n console.log(registration);\n await navigator.serviceWorker.ready;\n console.log(\"service worker ready\");\n await sleepMs(100);\n await fetch(`serviceworker-write?secret=${key}`);\n }","read":"async () => {\n console.log(\"trying to register the serviceworker now...\");\n const registration = await Promise.race([\n navigator.serviceWorker.register('serviceWorker.js'),\n sleepMs(500)\n ]);\n if (registration === undefined) {\n // We timed out or otherwise failed.\n throw new Error(\"ServiceWorker registration failed\");\n }\n console.log(registration);\n await navigator.serviceWorker.ready;\n console.log(\"service worker ready\");\n await sleepMs(100);\n let response = await fetch(\"serviceworker-read\");\n return await response.text();\n }","unsupported":false,"readSameFirstParty":"","readDifferentFirstParty":"","testFailed":true,"description":"The ServiceWorker API allows websites to run code in the background and store content in the browser for offline use. If a ServiceWorker can be accessed from multiple websites, it can be abused to track users across sites."},"CSS cache":{"write":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return key;\n }","read":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return fontFamily;\n }","unsupported":false,"readSameFirstParty":"fake_42952860144205474","readDifferentFirstParty":"fake_8710860000208402","passed":true,"testFailed":false,"description":"CSS stylesheets are cached, and if that cache is shared between websites, it can be used to track users across sites."},"font cache":{"write":"async (key) => {\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } body { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n return key;\n }","read":"async (key) => {\n const text = document.createElement(\"span\");\n text.id = \"text\";\n text.innerText = \"test\";\n document.body.appendChild(text);\n const originalWidth = text.getBoundingClientRect().width;\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } #text { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n let newWidth;\n do {\n await sleepMs(100);\n newWidth = text.getBoundingClientRect().width;\n } while (newWidth < 0 || newWidth === originalWidth)\n let response = await fetch(\n testURI(\"ctr\", \"font\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","unsupported":false,"readSameFirstParty":"2","readDifferentFirstParty":"3","passed":true,"testFailed":false,"description":"Web fonts are sometimes stored in their own cache, which is vulnerable to being abused for cross-site tracking."},"image cache":{"write":"(key) => new Promise((resolve, reject) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n img.addEventListener(\"load\", () => resolve(key), {once: true});\n img.src = testURI(\"resource\", \"image\", key);\n })","read":"async (key) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n let imgLoadPromise = new Promise((resolve, reject) => {\n img.addEventListener(\"load\", resolve, {once: true});\n });\n img.src = testURI(\"resource\", \"image\", key);\n await imgLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"image\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","unsupported":false,"readSameFirstParty":"2","readDifferentFirstParty":"3","passed":true,"testFailed":false,"description":"Caching of images in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking."},"script cache":{"write":"(key) => new Promise((resolve, reject) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n script.addEventListener(\"load\", () => resolve(key), {once: true});\n script.src = testURI(\"resource\", \"script\", key);\n })","read":"async (key) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n let scriptLoadPromise = new Promise((resolve, reject) => {\n script.addEventListener(\"load\", resolve, {once: true});\n });\n script.src = testURI(\"resource\", \"script\", key);\n await scriptLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"script\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","unsupported":false,"readSameFirstParty":"2","readDifferentFirstParty":"3","passed":true,"testFailed":false,"description":"Caching of scripts in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking."},"prefetch cache":{"write":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n return key;\n }","read":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n await sleepMs(500);\n let response = await fetch(\n testURI(\"ctr\", \"prefetch\", key), {\"cache\": \"reload\"});\n let countString = (await response.text()).trim();\n if (parseInt(countString) === 0) {\n throw new Error(\"No requests received\");\n }\n return countString;\n }","unsupported":true,"readSameFirstParty":"Error: No requests received","readDifferentFirstParty":"Error: No requests received","testFailed":false,"description":"A suggests to browsers they should fetch a resource ahead of time and cache it. But if browsers don't partition this cache, it can be used to track users across websites."},"Alt-Svc":{"write":"async () => {\n // Clear Alt-Svc caching first.\n let responseText = \"\";\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/clear\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after clear:\", responseText);\n // Store \"h3\" state in Alt-Svc cache\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/set\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after set:\", responseText);\n }","read":"async () => {\n const protocol = await fetchText(altSvcOrigin + \"/protocol\");\n if ((new URL(location)).searchParams.get(\"thirdparty\") === \"same\") {\n if (protocol !== \"h3\") {\n throw new Error(\"Unsupported\");\n }\n }\n return protocol;\n }","unsupported":true,"readSameFirstParty":"Error: Unsupported","readDifferentFirstParty":"h3","testFailed":false,"description":"Alt-Svc allows the server to indicate to the web browser that a resource should be loaded on a different server. Because this is a persistent setting, it could be used to track users across websites if it is not correctly partitioned."},"HSTS cache":{"description":"The HTTP Strict-Transport-Security response header allows a website to signal that it should only be accessed via HTTPS. The browser remembers this directive in a database, but if this database is not partitioned, then it can be used to track users across websites.\"","passed":true,"unsupported":false,"testFailed":false,"readDifferentFirstParty":"Used http","readSameFirstParty":"not tested","write":"set HSTS flag","read":"read HSTS flag"},"HSTS cache (fetch)":{"description":"The HTTP Strict-Transport-Security response header allows a website to signal that it should only be accessed via HTTPS. The browser remembers this directive in a database, but if this database is not partitioned, then it can be used to track users across websites.\"","passed":true,"unsupported":false,"testFailed":false,"readDifferentFirstParty":"Used http","readSameFirstParty":"not tested","write":"set HSTS flag","read":"read HSTS flag"}},"trackers":{"Google (third-party ad pixel)":{"url":"https://www.google.com/pagead/1p-user-list/","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://www.google.com/pagead/1p-user-list/"},"Google Tag Manager":{"url":"https://www.googletagmanager.com/gtag.js?id=GTM-NX4SMZL","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://www.googletagmanager.com/gtag.js?id=GTM-NX4SMZL"},"DoubleClick (Google)":{"url":"https://securepubads.g.doubleclick.net/static/glade.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://securepubads.g.doubleclick.net/static/glade.js"},"Google Analytics":{"url":"https://google-analytics.com/urchin.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://google-analytics.com/urchin.js"},"Facebook tracking":{"url":"https://connect.facebook.net/en_US/fbevents.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://connect.facebook.net/en_US/fbevents.js"},"Amazon adsystem":{"url":"https://s.amazon-adsystem.com/dcm","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://s.amazon-adsystem.com/dcm"},"Scorecard Research Beacon":{"url":"https://sb.scorecardresearch.com/internal-c2/default/cs.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://sb.scorecardresearch.com/internal-c2/default/cs.js"},"New Relic":{"url":"https://js-agent.newrelic.com/nr-1212.min.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://js-agent.newrelic.com/nr-1212.min.js"},"Criteo":{"url":"https://dis.criteo.com/dis/rtb/appnexus/cookiematch.aspx","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://dis.criteo.com/dis/rtb/appnexus/cookiematch.aspx"},"Adobe":{"url":"https://munchkin.marketo.net/munchkin.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://munchkin.marketo.net/munchkin.js"},"Adobe Audience Manager":{"url":"https://dpm.demdex.net/ibs","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://dpm.demdex.net/ibs"},"AppNexus":{"url":"https://ib.adnxs.com/px?id=178248&t=1","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://ib.adnxs.com/px?id=178248&t=1"},"Twitter pixel":{"url":"https://t.co/i/adsct","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://t.co/i/adsct"},"Bing Ads":{"url":"https://bat.bing.com/bat.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://bat.bing.com/bat.js"},"Taboola":{"url":"https://trc.taboola.com/futureplc-tomsguide/trc/3/json","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://trc.taboola.com/futureplc-tomsguide/trc/3/json"},"Index Exchange":{"url":"https://dsum-sec.casalemedia.com/crum?cm_dsp_id=10&external_user_id=629685505537&C=1","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://dsum-sec.casalemedia.com/crum?cm_dsp_id=10&external_user_id=629685505537&C=1"},"Yandex Ads":{"url":"https://yandex.ru/ads/system/header-bidding.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://yandex.ru/ads/system/header-bidding.js"},"Quantcast":{"url":"https://pixel.quantserve.com/pixel","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://pixel.quantserve.com/pixel"},"Chartbeat":{"url":"https://static.chartbeat.com/js/chartbeat.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://static.chartbeat.com/js/chartbeat.js"}}},"timeStarted":"2024-03-31T23:42:12.283Z","reportedVersion":"123.2420.56","os":"Darwin","os_version":"Darwin Kernel Version 23.4.0: Wed Feb 21 21:44:06 PST 2024; root:xnu-10063.101.15~2/RELEASE_ARM64_T8103"},{"browser":"edge","incognito":false,"tor":false,"nightly":false,"testResults":{"session_3p":{"cookie (JS)":{"unsupported":true,"testFailed":false,"write":"(secret) => {\n document.cookie = `secret=${secret}_js; max-age=3600; SameSite=None; Secure`;\n }","read":"() => document.cookie ? document.cookie.match(/secret=([\\w-]+)/)[1] : null","description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them.","readSameSession":null,"readDifferentSession":null},"cookie (HTTP)":{"unsupported":true,"testFailed":false,"write":"async (secret) => {\n // Request a page that will send an HTTPOnly 'set-cookie' response header with secret value.\n await fetch(`${baseURI}cookie?secret=${secret}_http`);\n }","read":"async () => {\n // Test if we now send a requests with a 'cookie' header containing the secret.\n let response = await fetch(`${baseURI}headers`);\n let cookie = (await response.json())[\"cookie\"];\n return cookie ? cookie.match(/secret=([\\w-]+)/)[1]: null;\n }","description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them.","readSameSession":null,"readDifferentSession":null},"localStorage":{"unsupported":false,"passed":true,"testFailed":false,"write":"(secret) => localStorage.setItem(\"secret\", secret)","read":"() => localStorage.getItem(\"secret\")","description":"The localStorage API gives websites access to a key-value database that will remain available across visits. If the localStorage API is not partitioned or blocked, it can also be used to track users across websites.","readSameSession":"1f874c53-f7eb-49f6-98d6-7b3b61b7de86_3p","readDifferentSession":null},"indexedDB":{"unsupported":false,"passed":true,"testFailed":false,"write":"async (secret) => {\n try {\n return await IdbKeyVal.set(\"secret\", secret);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"() => IdbKeyVal.get(\"secret\")","description":"The IndexedDB API exposes a transactional database to web pages. That database can be used to track users across websites, unless it is partitioned.","readSameSession":"1f874c53-f7eb-49f6-98d6-7b3b61b7de86_3p"},"fetch cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n return key;\n }","read":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n let countResponse = await fetch(testURI(\"ctr\", \"fetch\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","description":"When a resource is received via the Fetch API, it is frequently cached. That cache can potentially be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"XMLHttpRequest cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n return key;\n }","read":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n let countResponse = await fetch(testURI(\"ctr\", \"xhr\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","description":"Similar to the newer Fetch API, any resource received may be cached by the browser. The cache is potentially vulnerable to cross-site tracking attack.","readSameSession":"1","readDifferentSession":"1"},"iframe cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n iframe.addEventListener(\"load\", () => resolve(key), {once: true});\n iframe.src = testURI(\"resource\", \"page\", key);\n })","read":"async (key) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n let iframeLoadPromise = new Promise((resolve, reject) => {\n iframe.addEventListener(\"load\", resolve, {once: true});\n });\n let address = testURI(\"resource\", \"page\", key);\n iframe.src = address;\n await iframeLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"page\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"An iframe is an element in a web page than allows websites to embed a second web page. Caching of this web page could be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"CacheStorage":{"unsupported":false,"passed":true,"testFailed":false,"write":"async (key) => {\n try {\n let cache = await caches.open(\"supercookies\");\n cache.addAll([`test.css?key=${key}`]);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n let cache = await caches.open(\"supercookies\");\n let cacheKeys = await cache.keys();\n let url = cacheKeys[0].url;\n return (new URL(url)).searchParams.get(\"key\");\n }","description":"The Cache API is a content storage mechanism originally introduced to support ServiceWorkers. If the same Cache object is accessible to multiple websites, it can be abused to track users.","readSameSession":"1f874c53-f7eb-49f6-98d6-7b3b61b7de86_3p","readDifferentSession":"Error: undefined is not an object (evaluating 'cacheKeys[0].url')"},"favicon cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => key","read":"async (key) => {\n // Wait for the favicon to load (defined in supercookies.html)\n await sleepMs(2000);\n let response = await fetch(\n testURI(\"ctr\", \"favicon\", key), {\"cache\": \"reload\"});\n let count = (await response.text()).trim();\n if (count === \"0\") {\n throw new Error(\"No requests received\");\n }\n return count;\n }","description":"A favicon is an icon that represents a website, typically shown in browser tab and bookmarks menu. If the favicon cache is not partitioned, it can be used to track users across websites.","readSameSession":"1","readDifferentSession":"1"},"CookieStore":{"unsupported":true,"testFailed":false,"write":"(data) => {\n const msPerHour = 60 * 60 * 1000;\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n window.cookieStore.set({\n name: \"partition_test\",\n value: data,\n expires: Date.now() + msPerHour,\n sameSite: \"none\"\n });\n }","read":"async () => {\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n const cookie = await window.cookieStore.get(\"partition_test\");\n if (!cookie) {\n return null;\n }\n return cookie.value;\n }","description":"The Cookie Store API is an alternative asynchronous API for managing cookies, supported by some browsers.","readSameSession":"Error: Unsupported","readDifferentSession":"Error: Unsupported"},"CSS cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return key;\n }","read":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return fontFamily;\n }","description":"CSS stylesheets are cached, and if that cache is shared between websites, it can be used to track users across sites.","readSameSession":"fake_27628504749770655","readDifferentSession":"fake_27628504749770655"},"image cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n img.addEventListener(\"load\", () => resolve(key), {once: true});\n img.src = testURI(\"resource\", \"image\", key);\n })","read":"async (key) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n let imgLoadPromise = new Promise((resolve, reject) => {\n img.addEventListener(\"load\", resolve, {once: true});\n });\n img.src = testURI(\"resource\", \"image\", key);\n await imgLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"image\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Caching of images in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"script cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n script.addEventListener(\"load\", () => resolve(key), {once: true});\n script.src = testURI(\"resource\", \"script\", key);\n })","read":"async (key) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n let scriptLoadPromise = new Promise((resolve, reject) => {\n script.addEventListener(\"load\", resolve, {once: true});\n });\n script.src = testURI(\"resource\", \"script\", key);\n await scriptLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"script\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Caching of scripts in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"font cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } body { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n return key;\n }","read":"async (key) => {\n const text = document.createElement(\"span\");\n text.id = \"text\";\n text.innerText = \"test\";\n document.body.appendChild(text);\n const originalWidth = text.getBoundingClientRect().width;\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } #text { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n let newWidth;\n do {\n await sleepMs(100);\n newWidth = text.getBoundingClientRect().width;\n } while (newWidth < 0 || newWidth === originalWidth)\n let response = await fetch(\n testURI(\"ctr\", \"font\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Web fonts are sometimes stored in their own cache, which is vulnerable to being abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"prefetch cache":{"unsupported":true,"testFailed":false,"write":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n return key;\n }","read":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n await sleepMs(500);\n let response = await fetch(\n testURI(\"ctr\", \"prefetch\", key), {\"cache\": \"reload\"});\n let countString = (await response.text()).trim();\n if (parseInt(countString) === 0) {\n throw new Error(\"No requests received\");\n }\n return countString;\n }","description":"A suggests to browsers they should fetch a resource ahead of time and cache it. But if browsers don't partition this cache, it can be used to track users across websites.","readSameSession":"Error: No requests received","readDifferentSession":"Error: No requests received"},"Alt-Svc":{"unsupported":true,"testFailed":false,"write":"async () => {\n // Clear Alt-Svc caching first.\n let responseText = \"\";\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/clear\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after clear:\", responseText);\n // Store \"h3\" state in Alt-Svc cache\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/set\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after set:\", responseText);\n }","read":"async () => {\n const protocol = await fetchText(altSvcOrigin + \"/protocol\");\n if ((new URL(location)).searchParams.get(\"thirdparty\") === \"same\") {\n if (protocol !== \"h3\") {\n throw new Error(\"Unsupported\");\n }\n }\n return protocol;\n }","description":"Alt-Svc allows the server to indicate to the web browser that a resource should be loaded on a different server. Because this is a persistent setting, it could be used to track users across websites if it is not correctly partitioned.","readSameSession":"h2","readDifferentSession":"h3"}},"session_1p":{"cookie (JS)":{"unsupported":false,"passed":false,"testFailed":false,"write":"(secret) => {\n document.cookie = `secret=${secret}_js; max-age=3600; SameSite=None; Secure`;\n }","read":"() => document.cookie ? document.cookie.match(/secret=([\\w-]+)/)[1] : null","description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them.","readSameSession":"1f874c53-f7eb-49f6-98d6-7b3b61b7de86_1p_js","readDifferentSession":"1f874c53-f7eb-49f6-98d6-7b3b61b7de86_1p_js"},"cookie (HTTP)":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (secret) => {\n // Request a page that will send an HTTPOnly 'set-cookie' response header with secret value.\n await fetch(`${baseURI}cookie?secret=${secret}_http`);\n }","read":"async () => {\n // Test if we now send a requests with a 'cookie' header containing the secret.\n let response = await fetch(`${baseURI}headers`);\n let cookie = (await response.json())[\"cookie\"];\n return cookie ? cookie.match(/secret=([\\w-]+)/)[1]: null;\n }","description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them.","readSameSession":"1f874c53-f7eb-49f6-98d6-7b3b61b7de86_1p_http","readDifferentSession":"1f874c53-f7eb-49f6-98d6-7b3b61b7de86_1p_http"},"localStorage":{"unsupported":false,"passed":false,"testFailed":false,"write":"(secret) => localStorage.setItem(\"secret\", secret)","read":"() => localStorage.getItem(\"secret\")","description":"The localStorage API gives websites access to a key-value database that will remain available across visits. If the localStorage API is not partitioned or blocked, it can also be used to track users across websites.","readSameSession":"1f874c53-f7eb-49f6-98d6-7b3b61b7de86_1p","readDifferentSession":"1f874c53-f7eb-49f6-98d6-7b3b61b7de86_1p"},"indexedDB":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (secret) => {\n try {\n return await IdbKeyVal.set(\"secret\", secret);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"() => IdbKeyVal.get(\"secret\")","description":"The IndexedDB API exposes a transactional database to web pages. That database can be used to track users across websites, unless it is partitioned.","readSameSession":"1f874c53-f7eb-49f6-98d6-7b3b61b7de86_1p","readDifferentSession":"1f874c53-f7eb-49f6-98d6-7b3b61b7de86_1p"},"fetch cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n return key;\n }","read":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n let countResponse = await fetch(testURI(\"ctr\", \"fetch\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","description":"When a resource is received via the Fetch API, it is frequently cached. That cache can potentially be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"XMLHttpRequest cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n return key;\n }","read":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n let countResponse = await fetch(testURI(\"ctr\", \"xhr\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","description":"Similar to the newer Fetch API, any resource received may be cached by the browser. The cache is potentially vulnerable to cross-site tracking attack.","readSameSession":"1","readDifferentSession":"1"},"iframe cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n iframe.addEventListener(\"load\", () => resolve(key), {once: true});\n iframe.src = testURI(\"resource\", \"page\", key);\n })","read":"async (key) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n let iframeLoadPromise = new Promise((resolve, reject) => {\n iframe.addEventListener(\"load\", resolve, {once: true});\n });\n let address = testURI(\"resource\", \"page\", key);\n iframe.src = address;\n await iframeLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"page\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"An iframe is an element in a web page than allows websites to embed a second web page. Caching of this web page could be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"CacheStorage":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n try {\n let cache = await caches.open(\"supercookies\");\n cache.addAll([`test.css?key=${key}`]);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n let cache = await caches.open(\"supercookies\");\n let cacheKeys = await cache.keys();\n let url = cacheKeys[0].url;\n return (new URL(url)).searchParams.get(\"key\");\n }","description":"The Cache API is a content storage mechanism originally introduced to support ServiceWorkers. If the same Cache object is accessible to multiple websites, it can be abused to track users.","readSameSession":"18747aa0-a493-4b2f-8684-a70dc7fadf6a_1p","readDifferentSession":"18747aa0-a493-4b2f-8684-a70dc7fadf6a_1p"},"favicon cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => key","read":"async (key) => {\n // Wait for the favicon to load (defined in supercookies.html)\n await sleepMs(2000);\n let response = await fetch(\n testURI(\"ctr\", \"favicon\", key), {\"cache\": \"reload\"});\n let count = (await response.text()).trim();\n if (count === \"0\") {\n throw new Error(\"No requests received\");\n }\n return count;\n }","description":"A favicon is an icon that represents a website, typically shown in browser tab and bookmarks menu. If the favicon cache is not partitioned, it can be used to track users across websites.","readSameSession":"1","readDifferentSession":"1"},"CookieStore":{"unsupported":true,"testFailed":false,"write":"(data) => {\n const msPerHour = 60 * 60 * 1000;\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n window.cookieStore.set({\n name: \"partition_test\",\n value: data,\n expires: Date.now() + msPerHour,\n sameSite: \"none\"\n });\n }","read":"async () => {\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n const cookie = await window.cookieStore.get(\"partition_test\");\n if (!cookie) {\n return null;\n }\n return cookie.value;\n }","description":"The Cookie Store API is an alternative asynchronous API for managing cookies, supported by some browsers.","readSameSession":"Error: Unsupported","readDifferentSession":"Error: Unsupported"},"CSS cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return key;\n }","read":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return fontFamily;\n }","description":"CSS stylesheets are cached, and if that cache is shared between websites, it can be used to track users across sites.","readSameSession":"fake_9133452705961158","readDifferentSession":"fake_9133452705961158"},"image cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n img.addEventListener(\"load\", () => resolve(key), {once: true});\n img.src = testURI(\"resource\", \"image\", key);\n })","read":"async (key) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n let imgLoadPromise = new Promise((resolve, reject) => {\n img.addEventListener(\"load\", resolve, {once: true});\n });\n img.src = testURI(\"resource\", \"image\", key);\n await imgLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"image\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Caching of images in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"script cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n script.addEventListener(\"load\", () => resolve(key), {once: true});\n script.src = testURI(\"resource\", \"script\", key);\n })","read":"async (key) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n let scriptLoadPromise = new Promise((resolve, reject) => {\n script.addEventListener(\"load\", resolve, {once: true});\n });\n script.src = testURI(\"resource\", \"script\", key);\n await scriptLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"script\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Caching of scripts in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"font cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } body { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n return key;\n }","read":"async (key) => {\n const text = document.createElement(\"span\");\n text.id = \"text\";\n text.innerText = \"test\";\n document.body.appendChild(text);\n const originalWidth = text.getBoundingClientRect().width;\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } #text { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n let newWidth;\n do {\n await sleepMs(100);\n newWidth = text.getBoundingClientRect().width;\n } while (newWidth < 0 || newWidth === originalWidth)\n let response = await fetch(\n testURI(\"ctr\", \"font\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Web fonts are sometimes stored in their own cache, which is vulnerable to being abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"prefetch cache":{"unsupported":true,"testFailed":false,"write":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n return key;\n }","read":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n await sleepMs(500);\n let response = await fetch(\n testURI(\"ctr\", \"prefetch\", key), {\"cache\": \"reload\"});\n let countString = (await response.text()).trim();\n if (parseInt(countString) === 0) {\n throw new Error(\"No requests received\");\n }\n return countString;\n }","description":"A suggests to browsers they should fetch a resource ahead of time and cache it. But if browsers don't partition this cache, it can be used to track users across websites.","readSameSession":"Error: No requests received","readDifferentSession":"Error: No requests received"},"Alt-Svc":{"unsupported":true,"testFailed":false,"write":"async () => {\n // Clear Alt-Svc caching first.\n let responseText = \"\";\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/clear\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after clear:\", responseText);\n // Store \"h3\" state in Alt-Svc cache\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/set\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after set:\", responseText);\n }","read":"async () => {\n const protocol = await fetchText(altSvcOrigin + \"/protocol\");\n if ((new URL(location)).searchParams.get(\"thirdparty\") === \"same\") {\n if (protocol !== \"h3\") {\n throw new Error(\"Unsupported\");\n }\n }\n return protocol;\n }","description":"Alt-Svc allows the server to indicate to the web browser that a resource should be loaded on a different server. Because this is a persistent setting, it could be used to track users across websites if it is not correctly partitioned.","readSameSession":"h2","readDifferentSession":"h3"}},"misc":{"Tor enabled":{"IsTorExit":false,"passed":false,"description":"The Tor network sends the browser's web requests through a series of relays to hide a user's IP address, thereby helping to mask their identity and location. This test checks to see if the Tor network is being used by default."},"GPC enabled third-party":{"passed":false,"description":"The Global Privacy Control is an HTTP header that can be sent by a browser to instruct a visited website not to sell the user's personal data to other parties. This test checks to see if the GPC header is sent to third-party elements on the web page."},"ECH enabled":{"SNI_status":"plaintext","passed":false,"description":"Encrypted Client Hello (ECH) is a new protocol that hides the website you are visiting from third-party network eavesdroppers."},"Stream isolation":{"write":"() => {\n if (!usingTor) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n if (usingTor) {\n return ipAddress;\n } else {\n throw new Error(\"Unsupported\");\n }\n }","unsupported":true,"readSameFirstParty":"Error: Unsupported","readDifferentFirstParty":"Error: Unsupported","testFailed":false,"description":"Browsers that use Tor can use a different Tor circuit per top-level website."},"IP address leak":{"description":"IP addresses can be used to uniquely identify a large percentage of users. A proxy, VPN, or Tor can mask a user's IP address.","passed":false},"GPC enabled first-party":{"header value":"undefined","description":"The Global Privacy Control is an HTTP header that can be sent by a browser to instruct a website not to sell the user's personal data to third parties. This test checks to see if the GPC header is sent by default to the top-level website.","passed":false}},"query":{"fbclid":{"value":"534245130707274","passed":false,"description":"Facebook Click Identifier"},"gclid":{"value":"534245130707274","passed":false,"description":"Google Click Identifier"},"msclkid":{"value":"534245130707274","passed":false,"description":"Microsoft Click ID"},"mc_eid":{"value":"534245130707274","passed":false,"description":"Mailchimp Email ID (email recipient's address)"},"dclid":{"value":"534245130707274","passed":false,"description":"DoubleClick Click ID (Google)"},"oly_anon_id":{"value":"534245130707274","passed":false,"description":"Omeda marketing 'anonymous' customer id"},"oly_enc_id":{"value":"534245130707274","passed":false,"description":"Omeda marketing 'known' customer id"},"_openstat":{"value":"534245130707274","passed":false,"description":"Yandex tracking parameter"},"vero_conv":{"value":"534245130707274","passed":false,"description":"Vero tracking parameter"},"vero_id":{"value":"534245130707274","passed":false,"description":"Vero tracking parameter"},"wickedid":{"value":"534245130707274","passed":false,"description":"Wicked Reports e-commerce tracking"},"yclid":{"value":"534245130707274","passed":false,"description":"Yandex Click ID"},"__s":{"value":"534245130707274","passed":false,"description":"Drip.com email address tracking parameter"},"rb_clickid":{"value":"534245130707274","passed":false,"description":"Unknown high-entropy tracking parameter"},"s_cid":{"value":"534245130707274","passed":false,"description":"Adobe Site Catalyst tracking parameter"},"ml_subscriber":{"value":"534245130707274","passed":false,"description":"MailerLite email tracking"},"ml_subscriber_hash":{"value":"534245130707274","passed":false,"description":"MailerLite email tracking"},"_hsenc":{"value":"534245130707274","passed":false,"description":"HubSpot tracking parameter"},"__hssc":{"value":"534245130707274","passed":false,"description":"HubSpot tracking parameter"},"__hstc":{"value":"534245130707274","passed":false,"description":"HubSpot tracking parameter"},"__hsfp":{"value":"534245130707274","passed":false,"description":"HubSpot tracking parameter"},"hsCtaTracking":{"value":"534245130707274","passed":false,"description":"HubSpot tracking parameter"},"mkt_tok":{"value":"534245130707274","passed":false,"description":"Adobe Marketo tracking parameter"}},"https":{"Upgradable image":{"passed":true,"result":"upgraded","description":"Checks to see if the browser attempts to upgrade an insecure address for an image to HTTPS whenever possible."},"Upgradable script":{"passed":true,"result":"blocked","description":"Checks to see if the browser attempts to upgrade an insecure address for an script to HTTPS whenever possible."},"Upgradable hyperlink":{"upgraded":false,"passed":false,"description":"Checks to see if the user has clicked on a hyperlink to an insecure address, if the browser upgrades that address to HTTPS whenever possible."},"Upgradable address":{"upgraded":false,"passed":false,"description":"Checks to see if an insecure address entered into the browser's address bar is upgraded to HTTPS whenever possible."},"Insecure website warning":{"passed":false,"result":"Insecure website loaded","description":"Checks to see if the browser stops loading an insecure website and warns the user before giving them the option to continue. Known as HTTPS-Only Mode in some browsers."}},"fingerprinting":{"screenX":{"expression":"screenX","actual_value":0,"desired_min":0,"desired_max":10,"passed":true,"description":"Position, in pixels, of the left edge of the browser window on screen.","desired_min_value":0,"desired_max_value":10},"screenY":{"expression":"screenY","actual_value":0,"desired_min":0,"desired_max":10,"passed":true,"description":"Position, in pixels, of the top edge of the browser window on screen.","desired_min_value":0,"desired_max_value":10},"outerHeight":{"expression":"outerHeight","actual_value":561,"desired_min":"innerHeight - 10","desired_max":"innerHeight + 10","passed":false,"description":"Height of the browser window in pixels, including browser chrome.","desired_min_value":1456,"desired_max_value":1476},"screen.width":{"expression":"screen.width","actual_value":375,"desired_min":"innerWidth - 10","desired_max":"innerWidth + 10","passed":false,"description":"Width of the user's screen, in pixels.","desired_min_value":970,"desired_max_value":990},"screen.height":{"expression":"screen.height","actual_value":667,"desired_min":"innerHeight - 10","desired_max":"innerHeight + 10","passed":false,"description":"Height of the user's screen, in pixels.","desired_min_value":1456,"desired_max_value":1476},"Media query screen width":{"name":"Media query screen width","actual_value":375,"desired_min":"innerWidth - 10","desired_max":"innerWidth + 10","passed":false,"description":"Width of the user's screen in pixels.","desired_min_value":970,"desired_max_value":990},"Media query screen height":{"name":"Media query screen height","actual_value":667,"desired_min":"innerHeight - 10","desired_max":"innerHeight + 10","passed":false,"description":"Height of the user's screen in pixels.","desired_min_value":1456,"desired_max_value":1476}},"navigation":{"sessionStorage":{"write":"(secret) => sessionStorage.setItem(\"secret\", secret)","read":"() => sessionStorage.getItem(\"secret\")","unsupported":false,"readSameFirstParty":"1f874c53-f7eb-49f6-98d6-7b3b61b7de86","readDifferentFirstParty":null,"passed":true,"testFailed":false,"description":"The sessionStorage API is similar to the localStorage API, but it does not persist across tabs or across browser sessions. Nonetheless, it can be used to track users if they navigate from one website to another. This tracking can be thwarted by partitioning sessionStorage between websites."},"window.name":{"write":"(secret) => window.name = \"name_\" + secret","read":"() => window.name","unsupported":false,"readSameFirstParty":"name_1f874c53-f7eb-49f6-98d6-7b3b61b7de86","readDifferentFirstParty":"","passed":true,"testFailed":false,"description":"The window.name API allows websites to store data that will persist after the user has navigated the tab to a different website. This mechanism could be partitioned so that data is not allowed to persist between websites."},"document.referrer":{"write":"(secret) => { /* do nothing */ }","read":"() => document.referrer","unsupported":false,"readSameFirstParty":"https://test-pages.privacytests2.org/","readDifferentFirstParty":"https://test-pages.privacytests2.org/","passed":false,"testFailed":false,"description":"The Referer [sic] request header is a mechanism used by browsers to let a website know where the user is visiting from. This header is inherently tracking users across websites. In recent times, browsers have switched to a policy of trimming a referrer to convey less tracking information, but Referer continues to convey cross-site tracking data by default."}},"supercookies":{"cookie (JS)":{"write":"(secret) => {\n document.cookie = `secret=${secret}_js; max-age=3600; SameSite=None; Secure`;\n }","read":"() => document.cookie ? document.cookie.match(/secret=([\\w-]+)/)[1] : null","unsupported":false,"readSameFirstParty":"1f874c53-f7eb-49f6-98d6-7b3b61b7de86_js","readDifferentFirstParty":null,"passed":true,"testFailed":false,"description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them."},"cookie (HTTP)":{"write":"async (secret) => {\n // Request a page that will send an HTTPOnly 'set-cookie' response header with secret value.\n await fetch(`${baseURI}cookie?secret=${secret}_http`);\n }","read":"async () => {\n // Test if we now send a requests with a 'cookie' header containing the secret.\n let response = await fetch(`${baseURI}headers`);\n let cookie = (await response.json())[\"cookie\"];\n return cookie ? cookie.match(/secret=([\\w-]+)/)[1]: null;\n }","unsupported":false,"readSameFirstParty":"1f874c53-f7eb-49f6-98d6-7b3b61b7de86_http","readDifferentFirstParty":null,"passed":true,"testFailed":false,"description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them."},"localStorage":{"write":"(secret) => localStorage.setItem(\"secret\", secret)","read":"() => localStorage.getItem(\"secret\")","unsupported":false,"readSameFirstParty":"1f874c53-f7eb-49f6-98d6-7b3b61b7de86","readDifferentFirstParty":null,"passed":true,"testFailed":false,"description":"The localStorage API gives websites access to a key-value database that will remain available across visits. If the localStorage API is not partitioned or blocked, it can also be used to track users across websites."},"indexedDB":{"write":"async (secret) => {\n try {\n return await IdbKeyVal.set(\"secret\", secret);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"() => IdbKeyVal.get(\"secret\")","unsupported":false,"readSameFirstParty":"1f874c53-f7eb-49f6-98d6-7b3b61b7de86","passed":true,"testFailed":false,"description":"The IndexedDB API exposes a transactional database to web pages. That database can be used to track users across websites, unless it is partitioned."},"SharedWorker":{"write":"async (secret) => {\n try {\n let worker = new SharedWorker(\"supercookies_sharedworker.js\");\n worker.port.start();\n// console.log(\"worker\", worker);\n const messagePromise = new Promise((resolve) => {\n worker.port.onmessage = (e) => resolve(e.data);\n });\n worker.port.postMessage(secret);\n await messagePromise;\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n let worker = new SharedWorker(\"supercookies_sharedworker.js\");\n worker.port.start();\n const messagePromise = new Promise((resolve, reject) => {\n worker.port.onmessage = (e) => resolve(e.data);\n setTimeout(() => reject(new Error(\"no SharedWorker message received\")), 200);\n });\n worker.port.postMessage(\"request\");\n const message = await messagePromise;\n if (message === \"none\") {\n throw new Error(\"Unsupported\");\n }\n return message;\n }","unsupported":true,"readSameFirstParty":"Error: Unsupported","readDifferentFirstParty":"Error: Unsupported","testFailed":false,"description":"The SharedWorker API allows scripts from multiple tabs to share a background thread of computation. If SharedWorker is not partitioned, then it can be abused to shared data between websites in your browser."},"blob":{"write":"(secret) => {\n try {\n let blobURL = URL.createObjectURL(new Blob([secret]));\n fetch(`${baseURI}blob?mode=write&key=${secret}&blobUrl=${encodeURIComponent(blobURL)}`);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async (secret) => {\n let response = await fetch(`${baseURI}blob?mode=read&key=${secret}`);\n let result = await response.json();\n let blobUrl = decodeURIComponent(result.blobUrl);\n let blobResponse = await fetch(blobUrl);\n return blobResponse.text();\n }","unsupported":false,"readSameFirstParty":"Error: Load failed","readDifferentFirstParty":"Error: Load failed","testFailed":true,"description":"A 'blob URL' is a local reference to some raw data. Trackers can use a blob URL to share data between websites."},"BroadcastChannel":{"write":"(secret) => {\n try {\n let bc = new BroadcastChannel(\"secrets\");\n bc.onmessage = (event) => {\n if (event.data === \"request\") {\n bc.postMessage(secret);\n }\n };\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"() =>\n new Promise((resolve, reject) => {\n let bc = new BroadcastChannel(\"secrets\");\n bc.onmessage = (event) => {\n if (event.data !== \"request\") {\n resolve(event.data);\n }\n };\n bc.postMessage(\"request\");\n setTimeout(() => reject({message: \"no BroadcastChannel message\"}), 3000);\n })","unsupported":false,"readSameFirstParty":"Error: no BroadcastChannel message","readDifferentFirstParty":"Error: no BroadcastChannel message","testFailed":true,"description":"A BroadcastChannel is designed to send messages between tabs. In some browsers it can be used for cross-site communication and tracking."},"fetch cache":{"write":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n return key;\n }","read":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n let countResponse = await fetch(testURI(\"ctr\", \"fetch\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","unsupported":false,"readSameFirstParty":"1","readDifferentFirstParty":"2","passed":true,"testFailed":false,"description":"When a resource is received via the Fetch API, it is frequently cached. That cache can potentially be abused for cross-site tracking."},"XMLHttpRequest cache":{"write":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n return key;\n }","read":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n let countResponse = await fetch(testURI(\"ctr\", \"xhr\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","unsupported":false,"readSameFirstParty":"1","readDifferentFirstParty":"2","passed":true,"testFailed":false,"description":"Similar to the newer Fetch API, any resource received may be cached by the browser. The cache is potentially vulnerable to cross-site tracking attack."},"iframe cache":{"write":"(key) => new Promise((resolve, reject) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n iframe.addEventListener(\"load\", () => resolve(key), {once: true});\n iframe.src = testURI(\"resource\", \"page\", key);\n })","read":"async (key) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n let iframeLoadPromise = new Promise((resolve, reject) => {\n iframe.addEventListener(\"load\", resolve, {once: true});\n });\n let address = testURI(\"resource\", \"page\", key);\n iframe.src = address;\n await iframeLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"page\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","unsupported":false,"readSameFirstParty":"1","readDifferentFirstParty":"2","passed":true,"testFailed":false,"description":"An iframe is an element in a web page than allows websites to embed a second web page. Caching of this web page could be abused for cross-site tracking."},"CacheStorage":{"write":"async (key) => {\n try {\n let cache = await caches.open(\"supercookies\");\n cache.addAll([`test.css?key=${key}`]);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n let cache = await caches.open(\"supercookies\");\n let cacheKeys = await cache.keys();\n let url = cacheKeys[0].url;\n return (new URL(url)).searchParams.get(\"key\");\n }","unsupported":false,"readSameFirstParty":"1f874c53-f7eb-49f6-98d6-7b3b61b7de86","readDifferentFirstParty":"Error: undefined is not an object (evaluating 'cacheKeys[0].url')","passed":true,"testFailed":false,"description":"The Cache API is a content storage mechanism originally introduced to support ServiceWorkers. If the same Cache object is accessible to multiple websites, it can be abused to track users."},"favicon cache":{"write":"(key) => key","read":"async (key) => {\n // Wait for the favicon to load (defined in supercookies.html)\n await sleepMs(2000);\n let response = await fetch(\n testURI(\"ctr\", \"favicon\", key), {\"cache\": \"reload\"});\n let count = (await response.text()).trim();\n if (count === \"0\") {\n throw new Error(\"No requests received\");\n }\n return count;\n }","unsupported":false,"readSameFirstParty":"1","readDifferentFirstParty":"1","passed":false,"testFailed":false,"description":"A favicon is an icon that represents a website, typically shown in browser tab and bookmarks menu. If the favicon cache is not partitioned, it can be used to track users across websites."},"locks":{"write":"async (key) => {\n if (navigator.locks) {\n navigator.locks.request(key, lock => new Promise((f,r) => {}));\n let queryResult = await navigator.locks.query();\n return queryResult.held[0].clientId;\n } else {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n if (navigator.locks) {\n let queryResult = await navigator.locks.query();\n return queryResult.held[0].name;\n }\n }","unsupported":false,"readSameFirstParty":"Error: undefined is not an object (evaluating 'queryResult.held[0].name')","readDifferentFirstParty":"Error: undefined is not an object (evaluating 'queryResult.held[0].name')","testFailed":true,"description":"navigator.locks (only supported in some browsers) allows scripts on multiple tabs to coordinate. If this API is not partitioned, it can be used for cross-site tracking."},"TLS Session ID":{"write":"async () => {\n let results = await fetch(\"https://tls.privacytests2.org:8900/\");\n return (await results.json()).sessionId;\n }","read":"async () => {\n let results = await fetch(\"https://tls.privacytests2.org:8900/\");\n return (await results.json()).sessionId;\n }","unsupported":false,"readSameFirstParty":"e183413a2ad71761089da2ae17ad78e128c32fcd69544511f51b0ec5f5b0c5d5","readDifferentFirstParty":"f07d07776aed83766e51ca99dab00f472e8b5503ebddc3095310ca0ab167557e","passed":true,"testFailed":false,"description":"The TLS protocol is used by HTTPS to make connections secure. If the browser were to re-use a TLS session, then the session ID could be used to track users across websites."},"H1 connection":{"write":"async (secret) => {\n await fetch(`https://h1.privacytests2.org:8901/?mode=write&secret=${secret}`, {cache: \"no-store\"});\n }","read":"async () => {\n let response = await fetch(`https://h1.privacytests2.org:8901/?mode=read`, {cache: \"no-store\"});\n return await response.text();\n }","unsupported":false,"readSameFirstParty":"1f874c53-f7eb-49f6-98d6-7b3b61b7de86","readDifferentFirstParty":"","passed":true,"testFailed":false,"description":"HTTP/1.x are the classic web connection protocols. If these connections are re-used across websites, they can be used to track users."},"H2 connection":{"write":"async (secret) => {\n await fetch(`https://h2.privacytests2.org:8902/?mode=write&secret=${secret}`, {cache: \"no-store\"});\n }","read":"async () => {\n let response = await fetch(`https://h2.privacytests2.org:8902/?mode=read`, {cache: \"no-store\"});\n return await response.text();\n }","unsupported":false,"readSameFirstParty":"1f874c53-f7eb-49f6-98d6-7b3b61b7de86","readDifferentFirstParty":"","passed":true,"testFailed":false,"description":"HTTP/2 is a web connection protocol introduced in 2015. Some browsers re-use HTTP/2 connections across websites and can thus be used to track users."},"H3 connection":{"write":"async (secret) => {\n // Ensure that we can switch over to h3 via alt-svc:\n for (let i = 0; i<3; ++i) {\n await fetch(`https://h3.privacytests2.org:4434/connection_id`, {cache: \"no-store\"});\n await sleepMs(500);\n }\n // Are we now connecting over h3?\n let response = await fetch(`https://h3.privacytests2.org:4434/connection_id`, {cache: \"no-store\"});\n let text = await response.text();\n // Empty response text indicates we are not connecting over h3:\n if (text.trim() === \"\") {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n let response = await fetch(`https://h3.privacytests2.org:4434/connection_id`);\n return await response.text();\n }","unsupported":false,"readSameFirstParty":"fdb1024e2ac8931e24fc980da7859424","readDifferentFirstParty":"db8fe63c1b5b9fb467fe68f2db2c419a","passed":true,"testFailed":false,"description":"HTTP/3 is a new standard HTTP connection protocol, still in draft but widely supported by browsers. If it is not partitioned, it can be used to track users across websites."},"CookieStore":{"write":"(data) => {\n const msPerHour = 60 * 60 * 1000;\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n window.cookieStore.set({\n name: \"partition_test\",\n value: data,\n expires: Date.now() + msPerHour,\n sameSite: \"none\"\n });\n }","read":"async () => {\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n const cookie = await window.cookieStore.get(\"partition_test\");\n if (!cookie) {\n return null;\n }\n return cookie.value;\n }","unsupported":true,"readSameFirstParty":"Error: Unsupported","readDifferentFirstParty":"Error: Unsupported","testFailed":false,"description":"The Cookie Store API is an alternative asynchronous API for managing cookies, supported by some browsers."},"getDirectory":{"write":"async (secret) => {\n try {\n const root = await navigator.storage.getDirectory();\n const fileHandle = await root.getFileHandle(\"secret.txt\", { create: true });\n const stream = await fileHandle.createWritable();\n await stream.write(secret);\n await stream.close();\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n try {\n const root = await navigator.storage.getDirectory();\n const fileHandle = await root.getFileHandle(\"secret.txt\");\n const file = await fileHandle.getFile();\n return file.text();\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","unsupported":true,"readSameFirstParty":"","readDifferentFirstParty":"Error: Unsupported","testFailed":false,"description":"navigator.storage.getDirectory exposes a location for storing files to web content. In some cases, these files may be shared across tabs."},"ServiceWorker":{"write":"async (key) => {\n if (!navigator.serviceWorker) {\n throw new Error(\"Unsupported\");\n }\n let registration = await navigator.serviceWorker.register(\n 'serviceWorker.js');\n console.log(registration);\n await navigator.serviceWorker.ready;\n console.log(\"service worker ready\");\n await sleepMs(100);\n await fetch(`serviceworker-write?secret=${key}`);\n }","read":"async () => {\n console.log(\"trying to register the serviceworker now...\");\n const registration = await Promise.race([\n navigator.serviceWorker.register('serviceWorker.js'),\n sleepMs(500)\n ]);\n if (registration === undefined) {\n // We timed out or otherwise failed.\n throw new Error(\"ServiceWorker registration failed\");\n }\n console.log(registration);\n await navigator.serviceWorker.ready;\n console.log(\"service worker ready\");\n await sleepMs(100);\n let response = await fetch(\"serviceworker-read\");\n return await response.text();\n }","unsupported":false,"readSameFirstParty":"","readDifferentFirstParty":"","testFailed":true,"description":"The ServiceWorker API allows websites to run code in the background and store content in the browser for offline use. If a ServiceWorker can be accessed from multiple websites, it can be abused to track users across sites."},"CSS cache":{"write":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return key;\n }","read":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return fontFamily;\n }","unsupported":false,"readSameFirstParty":"fake_543893125893234","readDifferentFirstParty":"fake_112270928658317","passed":true,"testFailed":false,"description":"CSS stylesheets are cached, and if that cache is shared between websites, it can be used to track users across sites."},"font cache":{"write":"async (key) => {\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } body { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n return key;\n }","read":"async (key) => {\n const text = document.createElement(\"span\");\n text.id = \"text\";\n text.innerText = \"test\";\n document.body.appendChild(text);\n const originalWidth = text.getBoundingClientRect().width;\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } #text { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n let newWidth;\n do {\n await sleepMs(100);\n newWidth = text.getBoundingClientRect().width;\n } while (newWidth < 0 || newWidth === originalWidth)\n let response = await fetch(\n testURI(\"ctr\", \"font\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","unsupported":false,"readSameFirstParty":"2","readDifferentFirstParty":"3","passed":true,"testFailed":false,"description":"Web fonts are sometimes stored in their own cache, which is vulnerable to being abused for cross-site tracking."},"image cache":{"write":"(key) => new Promise((resolve, reject) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n img.addEventListener(\"load\", () => resolve(key), {once: true});\n img.src = testURI(\"resource\", \"image\", key);\n })","read":"async (key) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n let imgLoadPromise = new Promise((resolve, reject) => {\n img.addEventListener(\"load\", resolve, {once: true});\n });\n img.src = testURI(\"resource\", \"image\", key);\n await imgLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"image\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","unsupported":false,"readSameFirstParty":"2","readDifferentFirstParty":"3","passed":true,"testFailed":false,"description":"Caching of images in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking."},"script cache":{"write":"(key) => new Promise((resolve, reject) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n script.addEventListener(\"load\", () => resolve(key), {once: true});\n script.src = testURI(\"resource\", \"script\", key);\n })","read":"async (key) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n let scriptLoadPromise = new Promise((resolve, reject) => {\n script.addEventListener(\"load\", resolve, {once: true});\n });\n script.src = testURI(\"resource\", \"script\", key);\n await scriptLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"script\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","unsupported":false,"readSameFirstParty":"2","readDifferentFirstParty":"3","passed":true,"testFailed":false,"description":"Caching of scripts in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking."},"prefetch cache":{"write":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n return key;\n }","read":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n await sleepMs(500);\n let response = await fetch(\n testURI(\"ctr\", \"prefetch\", key), {\"cache\": \"reload\"});\n let countString = (await response.text()).trim();\n if (parseInt(countString) === 0) {\n throw new Error(\"No requests received\");\n }\n return countString;\n }","unsupported":true,"readSameFirstParty":"Error: No requests received","readDifferentFirstParty":"Error: No requests received","testFailed":false,"description":"A suggests to browsers they should fetch a resource ahead of time and cache it. But if browsers don't partition this cache, it can be used to track users across websites."},"Alt-Svc":{"write":"async () => {\n // Clear Alt-Svc caching first.\n let responseText = \"\";\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/clear\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after clear:\", responseText);\n // Store \"h3\" state in Alt-Svc cache\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/set\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after set:\", responseText);\n }","read":"async () => {\n const protocol = await fetchText(altSvcOrigin + \"/protocol\");\n if ((new URL(location)).searchParams.get(\"thirdparty\") === \"same\") {\n if (protocol !== \"h3\") {\n throw new Error(\"Unsupported\");\n }\n }\n return protocol;\n }","unsupported":true,"readSameFirstParty":"Error: Unsupported","readDifferentFirstParty":"h3","testFailed":false,"description":"Alt-Svc allows the server to indicate to the web browser that a resource should be loaded on a different server. Because this is a persistent setting, it could be used to track users across websites if it is not correctly partitioned."},"HSTS cache":{"description":"The HTTP Strict-Transport-Security response header allows a website to signal that it should only be accessed via HTTPS. The browser remembers this directive in a database, but if this database is not partitioned, then it can be used to track users across websites.\"","passed":true,"unsupported":false,"testFailed":false,"readDifferentFirstParty":"Used http","readSameFirstParty":"not tested","write":"set HSTS flag","read":"read HSTS flag"},"HSTS cache (fetch)":{"description":"The HTTP Strict-Transport-Security response header allows a website to signal that it should only be accessed via HTTPS. The browser remembers this directive in a database, but if this database is not partitioned, then it can be used to track users across websites.\"","passed":true,"unsupported":false,"testFailed":false,"readDifferentFirstParty":"Used http","readSameFirstParty":"not tested","write":"set HSTS flag","read":"read HSTS flag"}},"trackers":{"Google (third-party ad pixel)":{"url":"https://www.google.com/pagead/1p-user-list/","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://www.google.com/pagead/1p-user-list/"},"Google Tag Manager":{"url":"https://www.googletagmanager.com/gtag.js?id=GTM-NX4SMZL","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://www.googletagmanager.com/gtag.js?id=GTM-NX4SMZL"},"DoubleClick (Google)":{"url":"https://securepubads.g.doubleclick.net/static/glade.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://securepubads.g.doubleclick.net/static/glade.js"},"Google Analytics":{"url":"https://google-analytics.com/urchin.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://google-analytics.com/urchin.js"},"Facebook tracking":{"url":"https://connect.facebook.net/en_US/fbevents.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://connect.facebook.net/en_US/fbevents.js"},"Amazon adsystem":{"url":"https://s.amazon-adsystem.com/dcm","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://s.amazon-adsystem.com/dcm"},"Scorecard Research Beacon":{"url":"https://sb.scorecardresearch.com/internal-c2/default/cs.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://sb.scorecardresearch.com/internal-c2/default/cs.js"},"New Relic":{"url":"https://js-agent.newrelic.com/nr-1212.min.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://js-agent.newrelic.com/nr-1212.min.js"},"Criteo":{"url":"https://dis.criteo.com/dis/rtb/appnexus/cookiematch.aspx","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://dis.criteo.com/dis/rtb/appnexus/cookiematch.aspx"},"Adobe":{"url":"https://munchkin.marketo.net/munchkin.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://munchkin.marketo.net/munchkin.js"},"Adobe Audience Manager":{"url":"https://dpm.demdex.net/ibs","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://dpm.demdex.net/ibs"},"AppNexus":{"url":"https://ib.adnxs.com/px?id=178248&t=1","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://ib.adnxs.com/px?id=178248&t=1"},"Twitter pixel":{"url":"https://t.co/i/adsct","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://t.co/i/adsct"},"Bing Ads":{"url":"https://bat.bing.com/bat.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://bat.bing.com/bat.js"},"Taboola":{"url":"https://trc.taboola.com/futureplc-tomsguide/trc/3/json","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://trc.taboola.com/futureplc-tomsguide/trc/3/json"},"Index Exchange":{"url":"https://dsum-sec.casalemedia.com/crum?cm_dsp_id=10&external_user_id=629685505537&C=1","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://dsum-sec.casalemedia.com/crum?cm_dsp_id=10&external_user_id=629685505537&C=1"},"Yandex Ads":{"url":"https://yandex.ru/ads/system/header-bidding.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://yandex.ru/ads/system/header-bidding.js"},"Quantcast":{"url":"https://pixel.quantserve.com/pixel","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://pixel.quantserve.com/pixel"},"Chartbeat":{"url":"https://static.chartbeat.com/js/chartbeat.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://static.chartbeat.com/js/chartbeat.js"}}},"timeStarted":"2024-03-31T23:45:06.086Z","reportedVersion":"123.2420.56","os":"Darwin","os_version":"Darwin Kernel Version 23.4.0: Wed Feb 21 21:44:06 PST 2024; root:xnu-10063.101.15~2/RELEASE_ARM64_T8103"},{"browser":"edge","incognito":false,"tor":false,"nightly":false,"testResults":{"session_3p":{"cookie (JS)":{"unsupported":true,"testFailed":false,"write":"(secret) => {\n document.cookie = `secret=${secret}_js; max-age=3600; SameSite=None; Secure`;\n }","read":"() => document.cookie ? document.cookie.match(/secret=([\\w-]+)/)[1] : null","description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them.","readSameSession":null,"readDifferentSession":null},"cookie (HTTP)":{"unsupported":true,"testFailed":false,"write":"async (secret) => {\n // Request a page that will send an HTTPOnly 'set-cookie' response header with secret value.\n await fetch(`${baseURI}cookie?secret=${secret}_http`);\n }","read":"async () => {\n // Test if we now send a requests with a 'cookie' header containing the secret.\n let response = await fetch(`${baseURI}headers`);\n let cookie = (await response.json())[\"cookie\"];\n return cookie ? cookie.match(/secret=([\\w-]+)/)[1]: null;\n }","description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them.","readSameSession":null,"readDifferentSession":null},"localStorage":{"unsupported":false,"passed":true,"testFailed":false,"write":"(secret) => localStorage.setItem(\"secret\", secret)","read":"() => localStorage.getItem(\"secret\")","description":"The localStorage API gives websites access to a key-value database that will remain available across visits. If the localStorage API is not partitioned or blocked, it can also be used to track users across websites.","readSameSession":"c26b7b92-9670-4a29-a0b8-8ce4a1277817_3p","readDifferentSession":null},"indexedDB":{"unsupported":false,"passed":true,"testFailed":false,"write":"async (secret) => {\n try {\n return await IdbKeyVal.set(\"secret\", secret);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"() => IdbKeyVal.get(\"secret\")","description":"The IndexedDB API exposes a transactional database to web pages. That database can be used to track users across websites, unless it is partitioned.","readSameSession":"c26b7b92-9670-4a29-a0b8-8ce4a1277817_3p"},"fetch cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n return key;\n }","read":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n let countResponse = await fetch(testURI(\"ctr\", \"fetch\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","description":"When a resource is received via the Fetch API, it is frequently cached. That cache can potentially be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"XMLHttpRequest cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n return key;\n }","read":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n let countResponse = await fetch(testURI(\"ctr\", \"xhr\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","description":"Similar to the newer Fetch API, any resource received may be cached by the browser. The cache is potentially vulnerable to cross-site tracking attack.","readSameSession":"1","readDifferentSession":"1"},"iframe cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n iframe.addEventListener(\"load\", () => resolve(key), {once: true});\n iframe.src = testURI(\"resource\", \"page\", key);\n })","read":"async (key) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n let iframeLoadPromise = new Promise((resolve, reject) => {\n iframe.addEventListener(\"load\", resolve, {once: true});\n });\n let address = testURI(\"resource\", \"page\", key);\n iframe.src = address;\n await iframeLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"page\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"An iframe is an element in a web page than allows websites to embed a second web page. Caching of this web page could be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"CacheStorage":{"unsupported":false,"passed":true,"testFailed":false,"write":"async (key) => {\n try {\n let cache = await caches.open(\"supercookies\");\n cache.addAll([`test.css?key=${key}`]);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n let cache = await caches.open(\"supercookies\");\n let cacheKeys = await cache.keys();\n let url = cacheKeys[0].url;\n return (new URL(url)).searchParams.get(\"key\");\n }","description":"The Cache API is a content storage mechanism originally introduced to support ServiceWorkers. If the same Cache object is accessible to multiple websites, it can be abused to track users.","readSameSession":"c26b7b92-9670-4a29-a0b8-8ce4a1277817_3p","readDifferentSession":"Error: undefined is not an object (evaluating 'cacheKeys[0].url')"},"favicon cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => key","read":"async (key) => {\n // Wait for the favicon to load (defined in supercookies.html)\n await sleepMs(2000);\n let response = await fetch(\n testURI(\"ctr\", \"favicon\", key), {\"cache\": \"reload\"});\n let count = (await response.text()).trim();\n if (count === \"0\") {\n throw new Error(\"No requests received\");\n }\n return count;\n }","description":"A favicon is an icon that represents a website, typically shown in browser tab and bookmarks menu. If the favicon cache is not partitioned, it can be used to track users across websites.","readSameSession":"1","readDifferentSession":"1"},"CookieStore":{"unsupported":true,"testFailed":false,"write":"(data) => {\n const msPerHour = 60 * 60 * 1000;\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n window.cookieStore.set({\n name: \"partition_test\",\n value: data,\n expires: Date.now() + msPerHour,\n sameSite: \"none\"\n });\n }","read":"async () => {\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n const cookie = await window.cookieStore.get(\"partition_test\");\n if (!cookie) {\n return null;\n }\n return cookie.value;\n }","description":"The Cookie Store API is an alternative asynchronous API for managing cookies, supported by some browsers.","readSameSession":"Error: Unsupported","readDifferentSession":"Error: Unsupported"},"CSS cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return key;\n }","read":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return fontFamily;\n }","description":"CSS stylesheets are cached, and if that cache is shared between websites, it can be used to track users across sites.","readSameSession":"fake_6585637624788512","readDifferentSession":"fake_6585637624788512"},"image cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n img.addEventListener(\"load\", () => resolve(key), {once: true});\n img.src = testURI(\"resource\", \"image\", key);\n })","read":"async (key) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n let imgLoadPromise = new Promise((resolve, reject) => {\n img.addEventListener(\"load\", resolve, {once: true});\n });\n img.src = testURI(\"resource\", \"image\", key);\n await imgLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"image\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Caching of images in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"script cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n script.addEventListener(\"load\", () => resolve(key), {once: true});\n script.src = testURI(\"resource\", \"script\", key);\n })","read":"async (key) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n let scriptLoadPromise = new Promise((resolve, reject) => {\n script.addEventListener(\"load\", resolve, {once: true});\n });\n script.src = testURI(\"resource\", \"script\", key);\n await scriptLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"script\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Caching of scripts in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"font cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } body { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n return key;\n }","read":"async (key) => {\n const text = document.createElement(\"span\");\n text.id = \"text\";\n text.innerText = \"test\";\n document.body.appendChild(text);\n const originalWidth = text.getBoundingClientRect().width;\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } #text { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n let newWidth;\n do {\n await sleepMs(100);\n newWidth = text.getBoundingClientRect().width;\n } while (newWidth < 0 || newWidth === originalWidth)\n let response = await fetch(\n testURI(\"ctr\", \"font\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Web fonts are sometimes stored in their own cache, which is vulnerable to being abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"prefetch cache":{"unsupported":true,"testFailed":false,"write":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n return key;\n }","read":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n await sleepMs(500);\n let response = await fetch(\n testURI(\"ctr\", \"prefetch\", key), {\"cache\": \"reload\"});\n let countString = (await response.text()).trim();\n if (parseInt(countString) === 0) {\n throw new Error(\"No requests received\");\n }\n return countString;\n }","description":"A suggests to browsers they should fetch a resource ahead of time and cache it. But if browsers don't partition this cache, it can be used to track users across websites.","readSameSession":"Error: No requests received","readDifferentSession":"Error: No requests received"},"Alt-Svc":{"unsupported":true,"testFailed":false,"write":"async () => {\n // Clear Alt-Svc caching first.\n let responseText = \"\";\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/clear\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after clear:\", responseText);\n // Store \"h3\" state in Alt-Svc cache\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/set\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after set:\", responseText);\n }","read":"async () => {\n const protocol = await fetchText(altSvcOrigin + \"/protocol\");\n if ((new URL(location)).searchParams.get(\"thirdparty\") === \"same\") {\n if (protocol !== \"h3\") {\n throw new Error(\"Unsupported\");\n }\n }\n return protocol;\n }","description":"Alt-Svc allows the server to indicate to the web browser that a resource should be loaded on a different server. Because this is a persistent setting, it could be used to track users across websites if it is not correctly partitioned.","readSameSession":"h2","readDifferentSession":"h3"}},"session_1p":{"cookie (JS)":{"unsupported":false,"passed":false,"testFailed":false,"write":"(secret) => {\n document.cookie = `secret=${secret}_js; max-age=3600; SameSite=None; Secure`;\n }","read":"() => document.cookie ? document.cookie.match(/secret=([\\w-]+)/)[1] : null","description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them.","readSameSession":"c26b7b92-9670-4a29-a0b8-8ce4a1277817_1p_js","readDifferentSession":"c26b7b92-9670-4a29-a0b8-8ce4a1277817_1p_js"},"cookie (HTTP)":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (secret) => {\n // Request a page that will send an HTTPOnly 'set-cookie' response header with secret value.\n await fetch(`${baseURI}cookie?secret=${secret}_http`);\n }","read":"async () => {\n // Test if we now send a requests with a 'cookie' header containing the secret.\n let response = await fetch(`${baseURI}headers`);\n let cookie = (await response.json())[\"cookie\"];\n return cookie ? cookie.match(/secret=([\\w-]+)/)[1]: null;\n }","description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them.","readSameSession":"c26b7b92-9670-4a29-a0b8-8ce4a1277817_1p_http","readDifferentSession":"c26b7b92-9670-4a29-a0b8-8ce4a1277817_1p_http"},"localStorage":{"unsupported":false,"passed":false,"testFailed":false,"write":"(secret) => localStorage.setItem(\"secret\", secret)","read":"() => localStorage.getItem(\"secret\")","description":"The localStorage API gives websites access to a key-value database that will remain available across visits. If the localStorage API is not partitioned or blocked, it can also be used to track users across websites.","readSameSession":"c26b7b92-9670-4a29-a0b8-8ce4a1277817_1p","readDifferentSession":"c26b7b92-9670-4a29-a0b8-8ce4a1277817_1p"},"indexedDB":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (secret) => {\n try {\n return await IdbKeyVal.set(\"secret\", secret);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"() => IdbKeyVal.get(\"secret\")","description":"The IndexedDB API exposes a transactional database to web pages. That database can be used to track users across websites, unless it is partitioned.","readSameSession":"c26b7b92-9670-4a29-a0b8-8ce4a1277817_1p","readDifferentSession":"c26b7b92-9670-4a29-a0b8-8ce4a1277817_1p"},"fetch cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n return key;\n }","read":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n let countResponse = await fetch(testURI(\"ctr\", \"fetch\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","description":"When a resource is received via the Fetch API, it is frequently cached. That cache can potentially be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"XMLHttpRequest cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n return key;\n }","read":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n let countResponse = await fetch(testURI(\"ctr\", \"xhr\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","description":"Similar to the newer Fetch API, any resource received may be cached by the browser. The cache is potentially vulnerable to cross-site tracking attack.","readSameSession":"1","readDifferentSession":"1"},"iframe cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n iframe.addEventListener(\"load\", () => resolve(key), {once: true});\n iframe.src = testURI(\"resource\", \"page\", key);\n })","read":"async (key) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n let iframeLoadPromise = new Promise((resolve, reject) => {\n iframe.addEventListener(\"load\", resolve, {once: true});\n });\n let address = testURI(\"resource\", \"page\", key);\n iframe.src = address;\n await iframeLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"page\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"An iframe is an element in a web page than allows websites to embed a second web page. Caching of this web page could be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"CacheStorage":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n try {\n let cache = await caches.open(\"supercookies\");\n cache.addAll([`test.css?key=${key}`]);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n let cache = await caches.open(\"supercookies\");\n let cacheKeys = await cache.keys();\n let url = cacheKeys[0].url;\n return (new URL(url)).searchParams.get(\"key\");\n }","description":"The Cache API is a content storage mechanism originally introduced to support ServiceWorkers. If the same Cache object is accessible to multiple websites, it can be abused to track users.","readSameSession":"18747aa0-a493-4b2f-8684-a70dc7fadf6a_1p","readDifferentSession":"18747aa0-a493-4b2f-8684-a70dc7fadf6a_1p"},"favicon cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => key","read":"async (key) => {\n // Wait for the favicon to load (defined in supercookies.html)\n await sleepMs(2000);\n let response = await fetch(\n testURI(\"ctr\", \"favicon\", key), {\"cache\": \"reload\"});\n let count = (await response.text()).trim();\n if (count === \"0\") {\n throw new Error(\"No requests received\");\n }\n return count;\n }","description":"A favicon is an icon that represents a website, typically shown in browser tab and bookmarks menu. If the favicon cache is not partitioned, it can be used to track users across websites.","readSameSession":"1","readDifferentSession":"1"},"CookieStore":{"unsupported":true,"testFailed":false,"write":"(data) => {\n const msPerHour = 60 * 60 * 1000;\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n window.cookieStore.set({\n name: \"partition_test\",\n value: data,\n expires: Date.now() + msPerHour,\n sameSite: \"none\"\n });\n }","read":"async () => {\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n const cookie = await window.cookieStore.get(\"partition_test\");\n if (!cookie) {\n return null;\n }\n return cookie.value;\n }","description":"The Cookie Store API is an alternative asynchronous API for managing cookies, supported by some browsers.","readSameSession":"Error: Unsupported","readDifferentSession":"Error: Unsupported"},"CSS cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return key;\n }","read":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return fontFamily;\n }","description":"CSS stylesheets are cached, and if that cache is shared between websites, it can be used to track users across sites.","readSameSession":"fake_2947887179279016","readDifferentSession":"fake_2947887179279016"},"image cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n img.addEventListener(\"load\", () => resolve(key), {once: true});\n img.src = testURI(\"resource\", \"image\", key);\n })","read":"async (key) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n let imgLoadPromise = new Promise((resolve, reject) => {\n img.addEventListener(\"load\", resolve, {once: true});\n });\n img.src = testURI(\"resource\", \"image\", key);\n await imgLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"image\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Caching of images in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"script cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"(key) => new Promise((resolve, reject) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n script.addEventListener(\"load\", () => resolve(key), {once: true});\n script.src = testURI(\"resource\", \"script\", key);\n })","read":"async (key) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n let scriptLoadPromise = new Promise((resolve, reject) => {\n script.addEventListener(\"load\", resolve, {once: true});\n });\n script.src = testURI(\"resource\", \"script\", key);\n await scriptLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"script\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Caching of scripts in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"font cache":{"unsupported":false,"passed":false,"testFailed":false,"write":"async (key) => {\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } body { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n return key;\n }","read":"async (key) => {\n const text = document.createElement(\"span\");\n text.id = \"text\";\n text.innerText = \"test\";\n document.body.appendChild(text);\n const originalWidth = text.getBoundingClientRect().width;\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } #text { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n let newWidth;\n do {\n await sleepMs(100);\n newWidth = text.getBoundingClientRect().width;\n } while (newWidth < 0 || newWidth === originalWidth)\n let response = await fetch(\n testURI(\"ctr\", \"font\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","description":"Web fonts are sometimes stored in their own cache, which is vulnerable to being abused for cross-site tracking.","readSameSession":"1","readDifferentSession":"1"},"prefetch cache":{"unsupported":true,"testFailed":false,"write":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n return key;\n }","read":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n await sleepMs(500);\n let response = await fetch(\n testURI(\"ctr\", \"prefetch\", key), {\"cache\": \"reload\"});\n let countString = (await response.text()).trim();\n if (parseInt(countString) === 0) {\n throw new Error(\"No requests received\");\n }\n return countString;\n }","description":"A suggests to browsers they should fetch a resource ahead of time and cache it. But if browsers don't partition this cache, it can be used to track users across websites.","readSameSession":"Error: No requests received","readDifferentSession":"Error: No requests received"},"Alt-Svc":{"unsupported":false,"passed":true,"testFailed":false,"write":"async () => {\n // Clear Alt-Svc caching first.\n let responseText = \"\";\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/clear\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after clear:\", responseText);\n // Store \"h3\" state in Alt-Svc cache\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/set\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after set:\", responseText);\n }","read":"async () => {\n const protocol = await fetchText(altSvcOrigin + \"/protocol\");\n if ((new URL(location)).searchParams.get(\"thirdparty\") === \"same\") {\n if (protocol !== \"h3\") {\n throw new Error(\"Unsupported\");\n }\n }\n return protocol;\n }","description":"Alt-Svc allows the server to indicate to the web browser that a resource should be loaded on a different server. Because this is a persistent setting, it could be used to track users across websites if it is not correctly partitioned.","readSameSession":"h3","readDifferentSession":"h2"}},"misc":{"Tor enabled":{"IsTorExit":false,"passed":false,"description":"The Tor network sends the browser's web requests through a series of relays to hide a user's IP address, thereby helping to mask their identity and location. This test checks to see if the Tor network is being used by default."},"GPC enabled third-party":{"passed":false,"description":"The Global Privacy Control is an HTTP header that can be sent by a browser to instruct a visited website not to sell the user's personal data to other parties. This test checks to see if the GPC header is sent to third-party elements on the web page."},"ECH enabled":{"SNI_status":"plaintext","passed":false,"description":"Encrypted Client Hello (ECH) is a new protocol that hides the website you are visiting from third-party network eavesdroppers."},"Stream isolation":{"write":"() => {\n if (!usingTor) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n if (usingTor) {\n return ipAddress;\n } else {\n throw new Error(\"Unsupported\");\n }\n }","unsupported":true,"readSameFirstParty":"Error: Unsupported","readDifferentFirstParty":"Error: Unsupported","testFailed":false,"description":"Browsers that use Tor can use a different Tor circuit per top-level website."},"IP address leak":{"description":"IP addresses can be used to uniquely identify a large percentage of users. A proxy, VPN, or Tor can mask a user's IP address.","passed":false},"GPC enabled first-party":{"header value":"undefined","description":"The Global Privacy Control is an HTTP header that can be sent by a browser to instruct a website not to sell the user's personal data to third parties. This test checks to see if the GPC header is sent by default to the top-level website.","passed":false}},"query":{"fbclid":{"value":"534245130707274","passed":false,"description":"Facebook Click Identifier"},"gclid":{"value":"534245130707274","passed":false,"description":"Google Click Identifier"},"msclkid":{"value":"534245130707274","passed":false,"description":"Microsoft Click ID"},"mc_eid":{"value":"534245130707274","passed":false,"description":"Mailchimp Email ID (email recipient's address)"},"dclid":{"value":"534245130707274","passed":false,"description":"DoubleClick Click ID (Google)"},"oly_anon_id":{"value":"534245130707274","passed":false,"description":"Omeda marketing 'anonymous' customer id"},"oly_enc_id":{"value":"534245130707274","passed":false,"description":"Omeda marketing 'known' customer id"},"_openstat":{"value":"534245130707274","passed":false,"description":"Yandex tracking parameter"},"vero_conv":{"value":"534245130707274","passed":false,"description":"Vero tracking parameter"},"vero_id":{"value":"534245130707274","passed":false,"description":"Vero tracking parameter"},"wickedid":{"value":"534245130707274","passed":false,"description":"Wicked Reports e-commerce tracking"},"yclid":{"value":"534245130707274","passed":false,"description":"Yandex Click ID"},"__s":{"value":"534245130707274","passed":false,"description":"Drip.com email address tracking parameter"},"rb_clickid":{"value":"534245130707274","passed":false,"description":"Unknown high-entropy tracking parameter"},"s_cid":{"value":"534245130707274","passed":false,"description":"Adobe Site Catalyst tracking parameter"},"ml_subscriber":{"value":"534245130707274","passed":false,"description":"MailerLite email tracking"},"ml_subscriber_hash":{"value":"534245130707274","passed":false,"description":"MailerLite email tracking"},"_hsenc":{"value":"534245130707274","passed":false,"description":"HubSpot tracking parameter"},"__hssc":{"value":"534245130707274","passed":false,"description":"HubSpot tracking parameter"},"__hstc":{"value":"534245130707274","passed":false,"description":"HubSpot tracking parameter"},"__hsfp":{"value":"534245130707274","passed":false,"description":"HubSpot tracking parameter"},"hsCtaTracking":{"value":"534245130707274","passed":false,"description":"HubSpot tracking parameter"},"mkt_tok":{"value":"534245130707274","passed":false,"description":"Adobe Marketo tracking parameter"}},"https":{"Upgradable image":{"passed":true,"result":"upgraded","description":"Checks to see if the browser attempts to upgrade an insecure address for an image to HTTPS whenever possible."},"Upgradable script":{"passed":true,"result":"blocked","description":"Checks to see if the browser attempts to upgrade an insecure address for an script to HTTPS whenever possible."},"Upgradable hyperlink":{"upgraded":false,"passed":false,"description":"Checks to see if the user has clicked on a hyperlink to an insecure address, if the browser upgrades that address to HTTPS whenever possible."},"Upgradable address":{"upgraded":false,"passed":false,"description":"Checks to see if an insecure address entered into the browser's address bar is upgraded to HTTPS whenever possible."},"Insecure website warning":{"passed":false,"result":"Insecure website loaded","description":"Checks to see if the browser stops loading an insecure website and warns the user before giving them the option to continue. Known as HTTPS-Only Mode in some browsers."}},"fingerprinting":{"screenX":{"expression":"screenX","actual_value":0,"desired_min":0,"desired_max":10,"passed":true,"description":"Position, in pixels, of the left edge of the browser window on screen.","desired_min_value":0,"desired_max_value":10},"screenY":{"expression":"screenY","actual_value":0,"desired_min":0,"desired_max":10,"passed":true,"description":"Position, in pixels, of the top edge of the browser window on screen.","desired_min_value":0,"desired_max_value":10},"outerHeight":{"expression":"outerHeight","actual_value":561,"desired_min":"innerHeight - 10","desired_max":"innerHeight + 10","passed":false,"description":"Height of the browser window in pixels, including browser chrome.","desired_min_value":1456,"desired_max_value":1476},"screen.width":{"expression":"screen.width","actual_value":375,"desired_min":"innerWidth - 10","desired_max":"innerWidth + 10","passed":false,"description":"Width of the user's screen, in pixels.","desired_min_value":970,"desired_max_value":990},"screen.height":{"expression":"screen.height","actual_value":667,"desired_min":"innerHeight - 10","desired_max":"innerHeight + 10","passed":false,"description":"Height of the user's screen, in pixels.","desired_min_value":1456,"desired_max_value":1476},"Media query screen width":{"name":"Media query screen width","actual_value":375,"desired_min":"innerWidth - 10","desired_max":"innerWidth + 10","passed":false,"description":"Width of the user's screen in pixels.","desired_min_value":970,"desired_max_value":990},"Media query screen height":{"name":"Media query screen height","actual_value":667,"desired_min":"innerHeight - 10","desired_max":"innerHeight + 10","passed":false,"description":"Height of the user's screen in pixels.","desired_min_value":1456,"desired_max_value":1476}},"navigation":{"sessionStorage":{"write":"(secret) => sessionStorage.setItem(\"secret\", secret)","read":"() => sessionStorage.getItem(\"secret\")","unsupported":false,"readSameFirstParty":"c26b7b92-9670-4a29-a0b8-8ce4a1277817","readDifferentFirstParty":null,"passed":true,"testFailed":false,"description":"The sessionStorage API is similar to the localStorage API, but it does not persist across tabs or across browser sessions. Nonetheless, it can be used to track users if they navigate from one website to another. This tracking can be thwarted by partitioning sessionStorage between websites."},"window.name":{"write":"(secret) => window.name = \"name_\" + secret","read":"() => window.name","unsupported":false,"readSameFirstParty":"name_c26b7b92-9670-4a29-a0b8-8ce4a1277817","readDifferentFirstParty":"","passed":true,"testFailed":false,"description":"The window.name API allows websites to store data that will persist after the user has navigated the tab to a different website. This mechanism could be partitioned so that data is not allowed to persist between websites."},"document.referrer":{"write":"(secret) => { /* do nothing */ }","read":"() => document.referrer","unsupported":false,"readSameFirstParty":"https://test-pages.privacytests2.org/","readDifferentFirstParty":"https://test-pages.privacytests2.org/","passed":false,"testFailed":false,"description":"The Referer [sic] request header is a mechanism used by browsers to let a website know where the user is visiting from. This header is inherently tracking users across websites. In recent times, browsers have switched to a policy of trimming a referrer to convey less tracking information, but Referer continues to convey cross-site tracking data by default."}},"supercookies":{"cookie (JS)":{"write":"(secret) => {\n document.cookie = `secret=${secret}_js; max-age=3600; SameSite=None; Secure`;\n }","read":"() => document.cookie ? document.cookie.match(/secret=([\\w-]+)/)[1] : null","unsupported":false,"readSameFirstParty":"c26b7b92-9670-4a29-a0b8-8ce4a1277817_js","readDifferentFirstParty":null,"passed":true,"testFailed":false,"description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them."},"cookie (HTTP)":{"write":"async (secret) => {\n // Request a page that will send an HTTPOnly 'set-cookie' response header with secret value.\n await fetch(`${baseURI}cookie?secret=${secret}_http`);\n }","read":"async () => {\n // Test if we now send a requests with a 'cookie' header containing the secret.\n let response = await fetch(`${baseURI}headers`);\n let cookie = (await response.json())[\"cookie\"];\n return cookie ? cookie.match(/secret=([\\w-]+)/)[1]: null;\n }","unsupported":false,"readSameFirstParty":"c26b7b92-9670-4a29-a0b8-8ce4a1277817_http","readDifferentFirstParty":null,"passed":true,"testFailed":false,"description":"The cookie, first introduced by Netscape in 1994, is a small amount of data stored by your browser on a website's behalf. It has legitimate uses, but it is also the classic cross-site tracking mechanism, and today still the most popular method of tracking users across websites. Browsers can stop cookies from being used for cross-site tracking by either blocking or partitioning them."},"localStorage":{"write":"(secret) => localStorage.setItem(\"secret\", secret)","read":"() => localStorage.getItem(\"secret\")","unsupported":false,"readSameFirstParty":"c26b7b92-9670-4a29-a0b8-8ce4a1277817","readDifferentFirstParty":null,"passed":true,"testFailed":false,"description":"The localStorage API gives websites access to a key-value database that will remain available across visits. If the localStorage API is not partitioned or blocked, it can also be used to track users across websites."},"indexedDB":{"write":"async (secret) => {\n try {\n return await IdbKeyVal.set(\"secret\", secret);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"() => IdbKeyVal.get(\"secret\")","unsupported":false,"readSameFirstParty":"c26b7b92-9670-4a29-a0b8-8ce4a1277817","passed":true,"testFailed":false,"description":"The IndexedDB API exposes a transactional database to web pages. That database can be used to track users across websites, unless it is partitioned."},"SharedWorker":{"write":"async (secret) => {\n try {\n let worker = new SharedWorker(\"supercookies_sharedworker.js\");\n worker.port.start();\n// console.log(\"worker\", worker);\n const messagePromise = new Promise((resolve) => {\n worker.port.onmessage = (e) => resolve(e.data);\n });\n worker.port.postMessage(secret);\n await messagePromise;\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n let worker = new SharedWorker(\"supercookies_sharedworker.js\");\n worker.port.start();\n const messagePromise = new Promise((resolve, reject) => {\n worker.port.onmessage = (e) => resolve(e.data);\n setTimeout(() => reject(new Error(\"no SharedWorker message received\")), 200);\n });\n worker.port.postMessage(\"request\");\n const message = await messagePromise;\n if (message === \"none\") {\n throw new Error(\"Unsupported\");\n }\n return message;\n }","unsupported":true,"readSameFirstParty":"Error: Unsupported","readDifferentFirstParty":"Error: Unsupported","testFailed":false,"description":"The SharedWorker API allows scripts from multiple tabs to share a background thread of computation. If SharedWorker is not partitioned, then it can be abused to shared data between websites in your browser."},"blob":{"write":"(secret) => {\n try {\n let blobURL = URL.createObjectURL(new Blob([secret]));\n fetch(`${baseURI}blob?mode=write&key=${secret}&blobUrl=${encodeURIComponent(blobURL)}`);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async (secret) => {\n let response = await fetch(`${baseURI}blob?mode=read&key=${secret}`);\n let result = await response.json();\n let blobUrl = decodeURIComponent(result.blobUrl);\n let blobResponse = await fetch(blobUrl);\n return blobResponse.text();\n }","unsupported":false,"readSameFirstParty":"Error: Load failed","readDifferentFirstParty":"Error: Load failed","testFailed":true,"description":"A 'blob URL' is a local reference to some raw data. Trackers can use a blob URL to share data between websites."},"BroadcastChannel":{"write":"(secret) => {\n try {\n let bc = new BroadcastChannel(\"secrets\");\n bc.onmessage = (event) => {\n if (event.data === \"request\") {\n bc.postMessage(secret);\n }\n };\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"() =>\n new Promise((resolve, reject) => {\n let bc = new BroadcastChannel(\"secrets\");\n bc.onmessage = (event) => {\n if (event.data !== \"request\") {\n resolve(event.data);\n }\n };\n bc.postMessage(\"request\");\n setTimeout(() => reject({message: \"no BroadcastChannel message\"}), 3000);\n })","unsupported":false,"readSameFirstParty":"Error: no BroadcastChannel message","readDifferentFirstParty":"Error: no BroadcastChannel message","testFailed":true,"description":"A BroadcastChannel is designed to send messages between tabs. In some browsers it can be used for cross-site communication and tracking."},"fetch cache":{"write":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n return key;\n }","read":"async (key) => {\n let response = await fetch(testURI(\"resource\", \"fetch\", key),\n {cache: \"force-cache\"});\n let countResponse = await fetch(testURI(\"ctr\", \"fetch\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","unsupported":false,"readSameFirstParty":"1","readDifferentFirstParty":"2","passed":true,"testFailed":false,"description":"When a resource is received via the Fetch API, it is frequently cached. That cache can potentially be abused for cross-site tracking."},"XMLHttpRequest cache":{"write":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n return key;\n }","read":"async (key) => {\n const req = new XMLHttpRequest();\n const loadPromise = new Promise(resolve => req.addEventListener(\"load\", resolve));\n req.open(\"GET\", testURI(\"resource\", \"xhr\", key));\n req.send();\n await loadPromise;\n let countResponse = await fetch(testURI(\"ctr\", \"xhr\", key),\n {cache: \"reload\"});\n return (await countResponse.text()).trim();\n }","unsupported":false,"readSameFirstParty":"1","readDifferentFirstParty":"2","passed":true,"testFailed":false,"description":"Similar to the newer Fetch API, any resource received may be cached by the browser. The cache is potentially vulnerable to cross-site tracking attack."},"iframe cache":{"write":"(key) => new Promise((resolve, reject) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n iframe.addEventListener(\"load\", () => resolve(key), {once: true});\n iframe.src = testURI(\"resource\", \"page\", key);\n })","read":"async (key) => {\n let iframe = document.createElement(\"iframe\");\n document.body.appendChild(iframe);\n let iframeLoadPromise = new Promise((resolve, reject) => {\n iframe.addEventListener(\"load\", resolve, {once: true});\n });\n let address = testURI(\"resource\", \"page\", key);\n iframe.src = address;\n await iframeLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"page\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","unsupported":false,"readSameFirstParty":"1","readDifferentFirstParty":"2","passed":true,"testFailed":false,"description":"An iframe is an element in a web page than allows websites to embed a second web page. Caching of this web page could be abused for cross-site tracking."},"CacheStorage":{"write":"async (key) => {\n try {\n let cache = await caches.open(\"supercookies\");\n cache.addAll([`test.css?key=${key}`]);\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n let cache = await caches.open(\"supercookies\");\n let cacheKeys = await cache.keys();\n let url = cacheKeys[0].url;\n return (new URL(url)).searchParams.get(\"key\");\n }","unsupported":false,"readSameFirstParty":"c26b7b92-9670-4a29-a0b8-8ce4a1277817","readDifferentFirstParty":"Error: undefined is not an object (evaluating 'cacheKeys[0].url')","passed":true,"testFailed":false,"description":"The Cache API is a content storage mechanism originally introduced to support ServiceWorkers. If the same Cache object is accessible to multiple websites, it can be abused to track users."},"favicon cache":{"write":"(key) => key","read":"async (key) => {\n // Wait for the favicon to load (defined in supercookies.html)\n await sleepMs(2000);\n let response = await fetch(\n testURI(\"ctr\", \"favicon\", key), {\"cache\": \"reload\"});\n let count = (await response.text()).trim();\n if (count === \"0\") {\n throw new Error(\"No requests received\");\n }\n return count;\n }","unsupported":false,"readSameFirstParty":"1","readDifferentFirstParty":"1","passed":false,"testFailed":false,"description":"A favicon is an icon that represents a website, typically shown in browser tab and bookmarks menu. If the favicon cache is not partitioned, it can be used to track users across websites."},"locks":{"write":"async (key) => {\n if (navigator.locks) {\n navigator.locks.request(key, lock => new Promise((f,r) => {}));\n let queryResult = await navigator.locks.query();\n return queryResult.held[0].clientId;\n } else {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n if (navigator.locks) {\n let queryResult = await navigator.locks.query();\n return queryResult.held[0].name;\n }\n }","unsupported":false,"readSameFirstParty":"Error: undefined is not an object (evaluating 'queryResult.held[0].name')","readDifferentFirstParty":"Error: undefined is not an object (evaluating 'queryResult.held[0].name')","testFailed":true,"description":"navigator.locks (only supported in some browsers) allows scripts on multiple tabs to coordinate. If this API is not partitioned, it can be used for cross-site tracking."},"TLS Session ID":{"write":"async () => {\n let results = await fetch(\"https://tls.privacytests2.org:8900/\");\n return (await results.json()).sessionId;\n }","read":"async () => {\n let results = await fetch(\"https://tls.privacytests2.org:8900/\");\n return (await results.json()).sessionId;\n }","unsupported":false,"readSameFirstParty":"ef239ed33733a079fad82acfd09c9ffc2303d0b66c68896eea047d1527d0085c","readDifferentFirstParty":"2e41d8fd219b73b78f6a003b6f741f91a0d4b23d886760699c1853d3f8471e0c","passed":true,"testFailed":false,"description":"The TLS protocol is used by HTTPS to make connections secure. If the browser were to re-use a TLS session, then the session ID could be used to track users across websites."},"H1 connection":{"write":"async (secret) => {\n await fetch(`https://h1.privacytests2.org:8901/?mode=write&secret=${secret}`, {cache: \"no-store\"});\n }","read":"async () => {\n let response = await fetch(`https://h1.privacytests2.org:8901/?mode=read`, {cache: \"no-store\"});\n return await response.text();\n }","unsupported":false,"readSameFirstParty":"c26b7b92-9670-4a29-a0b8-8ce4a1277817","readDifferentFirstParty":"","passed":true,"testFailed":false,"description":"HTTP/1.x are the classic web connection protocols. If these connections are re-used across websites, they can be used to track users."},"H2 connection":{"write":"async (secret) => {\n await fetch(`https://h2.privacytests2.org:8902/?mode=write&secret=${secret}`, {cache: \"no-store\"});\n }","read":"async () => {\n let response = await fetch(`https://h2.privacytests2.org:8902/?mode=read`, {cache: \"no-store\"});\n return await response.text();\n }","unsupported":false,"readSameFirstParty":"c26b7b92-9670-4a29-a0b8-8ce4a1277817","readDifferentFirstParty":"","passed":true,"testFailed":false,"description":"HTTP/2 is a web connection protocol introduced in 2015. Some browsers re-use HTTP/2 connections across websites and can thus be used to track users."},"H3 connection":{"write":"async (secret) => {\n // Ensure that we can switch over to h3 via alt-svc:\n for (let i = 0; i<3; ++i) {\n await fetch(`https://h3.privacytests2.org:4434/connection_id`, {cache: \"no-store\"});\n await sleepMs(500);\n }\n // Are we now connecting over h3?\n let response = await fetch(`https://h3.privacytests2.org:4434/connection_id`, {cache: \"no-store\"});\n let text = await response.text();\n // Empty response text indicates we are not connecting over h3:\n if (text.trim() === \"\") {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n let response = await fetch(`https://h3.privacytests2.org:4434/connection_id`);\n return await response.text();\n }","unsupported":false,"readSameFirstParty":"0b72f40b57d8b4bd4abf67abcf47b996","readDifferentFirstParty":"7c88961be38141b8d6ca684383065e89","passed":true,"testFailed":false,"description":"HTTP/3 is a new standard HTTP connection protocol, still in draft but widely supported by browsers. If it is not partitioned, it can be used to track users across websites."},"CookieStore":{"write":"(data) => {\n const msPerHour = 60 * 60 * 1000;\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n window.cookieStore.set({\n name: \"partition_test\",\n value: data,\n expires: Date.now() + msPerHour,\n sameSite: \"none\"\n });\n }","read":"async () => {\n if (!window.cookieStore) {\n throw new Error(\"Unsupported\");\n }\n const cookie = await window.cookieStore.get(\"partition_test\");\n if (!cookie) {\n return null;\n }\n return cookie.value;\n }","unsupported":true,"readSameFirstParty":"Error: Unsupported","readDifferentFirstParty":"Error: Unsupported","testFailed":false,"description":"The Cookie Store API is an alternative asynchronous API for managing cookies, supported by some browsers."},"getDirectory":{"write":"async (secret) => {\n try {\n const root = await navigator.storage.getDirectory();\n const fileHandle = await root.getFileHandle(\"secret.txt\", { create: true });\n const stream = await fileHandle.createWritable();\n await stream.write(secret);\n await stream.close();\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","read":"async () => {\n try {\n const root = await navigator.storage.getDirectory();\n const fileHandle = await root.getFileHandle(\"secret.txt\");\n const file = await fileHandle.getFile();\n return file.text();\n } catch (e) {\n throw new Error(\"Unsupported\");\n }\n }","unsupported":true,"readSameFirstParty":"","readDifferentFirstParty":"Error: Unsupported","testFailed":false,"description":"navigator.storage.getDirectory exposes a location for storing files to web content. In some cases, these files may be shared across tabs."},"ServiceWorker":{"write":"async (key) => {\n if (!navigator.serviceWorker) {\n throw new Error(\"Unsupported\");\n }\n let registration = await navigator.serviceWorker.register(\n 'serviceWorker.js');\n console.log(registration);\n await navigator.serviceWorker.ready;\n console.log(\"service worker ready\");\n await sleepMs(100);\n await fetch(`serviceworker-write?secret=${key}`);\n }","read":"async () => {\n console.log(\"trying to register the serviceworker now...\");\n const registration = await Promise.race([\n navigator.serviceWorker.register('serviceWorker.js'),\n sleepMs(500)\n ]);\n if (registration === undefined) {\n // We timed out or otherwise failed.\n throw new Error(\"ServiceWorker registration failed\");\n }\n console.log(registration);\n await navigator.serviceWorker.ready;\n console.log(\"service worker ready\");\n await sleepMs(100);\n let response = await fetch(\"serviceworker-read\");\n return await response.text();\n }","unsupported":false,"readSameFirstParty":"","readDifferentFirstParty":"","testFailed":true,"description":"The ServiceWorker API allows websites to run code in the background and store content in the browser for offline use. If a ServiceWorker can be accessed from multiple websites, it can be abused to track users across sites."},"CSS cache":{"write":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return key;\n }","read":"async (key) => {\n const href = testURI(\"resource\", \"css\", key);\n const head = document.getElementsByTagName(\"head\")[0];\n head.innerHTML += ``;\n const testElement = document.querySelector(\"#css\");\n let fontFamily;\n while (true) {\n await sleepMs(100);\n fontFamily = getComputedStyle(testElement).fontFamily;\n if (fontFamily.startsWith(\"fake\")) {\n break;\n }\n }\n console.log(fontFamily);\n return fontFamily;\n }","unsupported":false,"readSameFirstParty":"fake_5077793889816478","readDifferentFirstParty":"fake_4468123948686622","passed":true,"testFailed":false,"description":"CSS stylesheets are cached, and if that cache is shared between websites, it can be used to track users across sites."},"font cache":{"write":"async (key) => {\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } body { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n return key;\n }","read":"async (key) => {\n const text = document.createElement(\"span\");\n text.id = \"text\";\n text.innerText = \"test\";\n document.body.appendChild(text);\n const originalWidth = text.getBoundingClientRect().width;\n let style = document.createElement(\"style\");\n style.type='text/css';\n let fontURI = testURI(\"resource\", \"font\", key);\n style.innerHTML = `@font-face {font-family: \"myFont\"; src: url(\"${fontURI}\"); } #text { font-family: \"myFont\" }`;\n document.getElementsByTagName(\"head\")[0].appendChild(style);\n let newWidth;\n do {\n await sleepMs(100);\n newWidth = text.getBoundingClientRect().width;\n } while (newWidth < 0 || newWidth === originalWidth)\n let response = await fetch(\n testURI(\"ctr\", \"font\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","unsupported":false,"readSameFirstParty":"2","readDifferentFirstParty":"3","passed":true,"testFailed":false,"description":"Web fonts are sometimes stored in their own cache, which is vulnerable to being abused for cross-site tracking."},"image cache":{"write":"(key) => new Promise((resolve, reject) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n img.addEventListener(\"load\", () => resolve(key), {once: true});\n img.src = testURI(\"resource\", \"image\", key);\n })","read":"async (key) => {\n let img = document.createElement(\"img\");\n document.body.appendChild(img);\n let imgLoadPromise = new Promise((resolve, reject) => {\n img.addEventListener(\"load\", resolve, {once: true});\n });\n img.src = testURI(\"resource\", \"image\", key);\n await imgLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"image\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","unsupported":false,"readSameFirstParty":"2","readDifferentFirstParty":"3","passed":true,"testFailed":false,"description":"Caching of images in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking."},"script cache":{"write":"(key) => new Promise((resolve, reject) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n script.addEventListener(\"load\", () => resolve(key), {once: true});\n script.src = testURI(\"resource\", \"script\", key);\n })","read":"async (key) => {\n let script = document.createElement(\"script\");\n document.body.appendChild(script);\n let scriptLoadPromise = new Promise((resolve, reject) => {\n script.addEventListener(\"load\", resolve, {once: true});\n });\n script.src = testURI(\"resource\", \"script\", key);\n await scriptLoadPromise;\n let response = await fetch(\n testURI(\"ctr\", \"script\", key), {\"cache\": \"reload\"});\n return (await response.text()).trim();\n }","unsupported":false,"readSameFirstParty":"2","readDifferentFirstParty":"3","passed":true,"testFailed":false,"description":"Caching of scripts in web browsers is a standard behavior. But if that cache leaks between websites, it can be abused for cross-site tracking."},"prefetch cache":{"write":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n return key;\n }","read":"async (key) => {\n let link = document.createElement(\"link\");\n link.rel = \"prefetch\";\n link.href = testURI(\"resource\", \"prefetch\", key);\n document.getElementsByTagName(\"head\")[0].appendChild(link);\n await sleepMs(500);\n let response = await fetch(\n testURI(\"ctr\", \"prefetch\", key), {\"cache\": \"reload\"});\n let countString = (await response.text()).trim();\n if (parseInt(countString) === 0) {\n throw new Error(\"No requests received\");\n }\n return countString;\n }","unsupported":true,"readSameFirstParty":"Error: No requests received","readDifferentFirstParty":"Error: No requests received","testFailed":false,"description":"A suggests to browsers they should fetch a resource ahead of time and cache it. But if browsers don't partition this cache, it can be used to track users across websites."},"Alt-Svc":{"write":"async () => {\n // Clear Alt-Svc caching first.\n let responseText = \"\";\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/clear\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after clear:\", responseText);\n // Store \"h3\" state in Alt-Svc cache\n for (let i = 0; i < 3; ++i) {\n await fetch(altSvcOrigin + \"/set\");\n await sleepMs(100);\n }\n responseText = await fetchText(altSvcOrigin + \"/protocol\");\n console.log(\"after set:\", responseText);\n }","read":"async () => {\n const protocol = await fetchText(altSvcOrigin + \"/protocol\");\n if ((new URL(location)).searchParams.get(\"thirdparty\") === \"same\") {\n if (protocol !== \"h3\") {\n throw new Error(\"Unsupported\");\n }\n }\n return protocol;\n }","unsupported":true,"readSameFirstParty":"Error: Unsupported","readDifferentFirstParty":"h3","testFailed":false,"description":"Alt-Svc allows the server to indicate to the web browser that a resource should be loaded on a different server. Because this is a persistent setting, it could be used to track users across websites if it is not correctly partitioned."},"HSTS cache":{"description":"The HTTP Strict-Transport-Security response header allows a website to signal that it should only be accessed via HTTPS. The browser remembers this directive in a database, but if this database is not partitioned, then it can be used to track users across websites.\"","passed":true,"unsupported":false,"testFailed":false,"readDifferentFirstParty":"Used http","readSameFirstParty":"not tested","write":"set HSTS flag","read":"read HSTS flag"},"HSTS cache (fetch)":{"description":"The HTTP Strict-Transport-Security response header allows a website to signal that it should only be accessed via HTTPS. The browser remembers this directive in a database, but if this database is not partitioned, then it can be used to track users across websites.\"","passed":true,"unsupported":false,"testFailed":false,"readDifferentFirstParty":"Used http","readSameFirstParty":"not tested","write":"set HSTS flag","read":"read HSTS flag"}},"trackers":{"Google (third-party ad pixel)":{"url":"https://www.google.com/pagead/1p-user-list/","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://www.google.com/pagead/1p-user-list/"},"Google Tag Manager":{"url":"https://www.googletagmanager.com/gtag.js?id=GTM-NX4SMZL","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://www.googletagmanager.com/gtag.js?id=GTM-NX4SMZL"},"DoubleClick (Google)":{"url":"https://securepubads.g.doubleclick.net/static/glade.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://securepubads.g.doubleclick.net/static/glade.js"},"Google Analytics":{"url":"https://google-analytics.com/urchin.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://google-analytics.com/urchin.js"},"Facebook tracking":{"url":"https://connect.facebook.net/en_US/fbevents.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://connect.facebook.net/en_US/fbevents.js"},"Amazon adsystem":{"url":"https://s.amazon-adsystem.com/dcm","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://s.amazon-adsystem.com/dcm"},"Scorecard Research Beacon":{"url":"https://sb.scorecardresearch.com/internal-c2/default/cs.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://sb.scorecardresearch.com/internal-c2/default/cs.js"},"New Relic":{"url":"https://js-agent.newrelic.com/nr-1212.min.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://js-agent.newrelic.com/nr-1212.min.js"},"Criteo":{"url":"https://dis.criteo.com/dis/rtb/appnexus/cookiematch.aspx","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://dis.criteo.com/dis/rtb/appnexus/cookiematch.aspx"},"Adobe":{"url":"https://munchkin.marketo.net/munchkin.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://munchkin.marketo.net/munchkin.js"},"Adobe Audience Manager":{"url":"https://dpm.demdex.net/ibs","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://dpm.demdex.net/ibs"},"AppNexus":{"url":"https://ib.adnxs.com/px?id=178248&t=1","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://ib.adnxs.com/px?id=178248&t=1"},"Twitter pixel":{"url":"https://t.co/i/adsct","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://t.co/i/adsct"},"Bing Ads":{"url":"https://bat.bing.com/bat.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://bat.bing.com/bat.js"},"Taboola":{"url":"https://trc.taboola.com/futureplc-tomsguide/trc/3/json","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://trc.taboola.com/futureplc-tomsguide/trc/3/json"},"Index Exchange":{"url":"https://dsum-sec.casalemedia.com/crum?cm_dsp_id=10&external_user_id=629685505537&C=1","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://dsum-sec.casalemedia.com/crum?cm_dsp_id=10&external_user_id=629685505537&C=1"},"Yandex Ads":{"url":"https://yandex.ru/ads/system/header-bidding.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://yandex.ru/ads/system/header-bidding.js"},"Quantcast":{"url":"https://pixel.quantserve.com/pixel","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://pixel.quantserve.com/pixel"},"Chartbeat":{"url":"https://static.chartbeat.com/js/chartbeat.js","passed":false,"description":"Tests whether the browser blocks the page from loading the tracker at https://static.chartbeat.com/js/chartbeat.js"}}},"timeStarted":"2024-03-31T23:48:01.720Z","reportedVersion":"123.2420.56","os":"Darwin","os_version":"Darwin Kernel Version 23.4.0: Wed Feb 21 21:44:06 PST 2024; root:xnu-10063.101.15~2/RELEASE_ARM64_T8103"}],"git":"df70d4bb9698ef17c4600ff50c083ba2954e5c5d","timeStarted":"2024-03-31T23:36:18.246Z","timeStopped":"2024-03-31T23:50:59.153Z","platform":"iOS"} \ No newline at end of file diff --git a/archive/issue84/ios-preview.png b/archive/issue84/ios-preview.png index 76165d91871af45a31b2e8263bbbde9add137c2a..6c17a855c2c701f1bcc674baeb591ca05df87236 100644 GIT binary patch literal 116078 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 z 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�e!&-6NfX1Y{(vYS{}d99 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 diff --git a/archive/issue84/ios.html b/archive/issue84/ios.html index 96ea78e7..55a2571a 100644 --- a/archive/issue84/ios.html +++ b/archive/issue84/ios.html @@ -386,9 +386,9 @@

bsm7r>ad)DKB#{s5iXHmb&{J=K6eh+#u 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 }*PR?Q}(q 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