summaryrefslogtreecommitdiffstats
path: root/toolkit/components/antitracking/test/browser/browser_AntiTrackingETPHeuristic.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/antitracking/test/browser/browser_AntiTrackingETPHeuristic.js')
-rw-r--r--toolkit/components/antitracking/test/browser/browser_AntiTrackingETPHeuristic.js261
1 files changed, 261 insertions, 0 deletions
diff --git a/toolkit/components/antitracking/test/browser/browser_AntiTrackingETPHeuristic.js b/toolkit/components/antitracking/test/browser/browser_AntiTrackingETPHeuristic.js
new file mode 100644
index 0000000000..f5274d8ba9
--- /dev/null
+++ b/toolkit/components/antitracking/test/browser/browser_AntiTrackingETPHeuristic.js
@@ -0,0 +1,261 @@
+"use strict";
+
+const TEST_PAGE = TEST_DOMAIN + TEST_PATH + "page.html";
+const TEST_REDIRECT_PAGE = TEST_DOMAIN + TEST_PATH + "redirect.sjs";
+const TEST_TRACKING_PAGE = TEST_3RD_PARTY_DOMAIN + TEST_PATH + "page.html";
+const TEST_TRACKING_REDIRECT_PAGE =
+ TEST_3RD_PARTY_DOMAIN + TEST_PATH + "redirect.sjs";
+const TEST_ANOTHER_TRACKING_REDIRECT_PAGE =
+ TEST_ANOTHER_3RD_PARTY_DOMAIN_HTTPS + TEST_PATH + "redirect.sjs";
+
+const TEST_CASES = [
+ // Tracker(Interacted) -> Non-Tracker
+ {
+ trackersHasUserInteraction: [TEST_3RD_PARTY_DOMAIN],
+ redirects: [TEST_TRACKING_REDIRECT_PAGE, TEST_PAGE],
+ expectedPermissionNumber: 1,
+ expects: [
+ [
+ TEST_DOMAIN,
+ TEST_3RD_PARTY_DOMAIN,
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ ],
+ ],
+ },
+ // Tracker(No interaction) -> Non-Tracker
+ {
+ trackersHasUserInteraction: [],
+ redirects: [TEST_TRACKING_REDIRECT_PAGE, TEST_PAGE],
+ expectedPermissionNumber: 0,
+ expects: [
+ [
+ TEST_DOMAIN,
+ TEST_3RD_PARTY_DOMAIN,
+ Ci.nsIPermissionManager.UNKNOWN_ACTION,
+ ],
+ ],
+ },
+ // Non-Tracker -> Tracker(Interacted) -> Non-Tracker
+ {
+ trackersHasUserInteraction: [TEST_3RD_PARTY_DOMAIN],
+ redirects: [TEST_REDIRECT_PAGE, TEST_TRACKING_REDIRECT_PAGE, TEST_PAGE],
+ expectedPermissionNumber: 1,
+ expects: [
+ [
+ TEST_DOMAIN,
+ TEST_3RD_PARTY_DOMAIN,
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ ],
+ ],
+ },
+ // Tracker(Interacted) -> Tracker(Interacted) -> Tracker(Interacted)
+ {
+ trackersHasUserInteraction: [TEST_3RD_PARTY_DOMAIN],
+ redirects: [
+ TEST_TRACKING_REDIRECT_PAGE,
+ TEST_TRACKING_REDIRECT_PAGE,
+ TEST_TRACKING_PAGE,
+ ],
+ expectedPermissionNumber: 0,
+ expects: [
+ [
+ TEST_3RD_PARTY_DOMAIN,
+ TEST_3RD_PARTY_DOMAIN,
+ Ci.nsIPermissionManager.UNKNOWN_ACTION,
+ ],
+ ],
+ },
+ // Tracker1(Interacted) -> Tracker2(Interacted) -> Non-Tracker
+ {
+ trackersHasUserInteraction: [
+ TEST_3RD_PARTY_DOMAIN,
+ TEST_ANOTHER_3RD_PARTY_DOMAIN_HTTPS,
+ ],
+ redirects: [
+ TEST_TRACKING_REDIRECT_PAGE,
+ TEST_ANOTHER_TRACKING_REDIRECT_PAGE,
+ TEST_PAGE,
+ ],
+ expectedPermissionNumber: 1,
+ expects: [
+ [
+ TEST_DOMAIN,
+ TEST_ANOTHER_3RD_PARTY_DOMAIN_HTTPS,
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ ],
+ ],
+ },
+ // Tracker1(Interacted) -> Non-Tracker -> Tracker2(No interaction) -> Non-Tracker
+ {
+ trackersHasUserInteraction: [TEST_3RD_PARTY_DOMAIN],
+ redirects: [
+ TEST_TRACKING_REDIRECT_PAGE,
+ TEST_REDIRECT_PAGE,
+ TEST_ANOTHER_TRACKING_REDIRECT_PAGE,
+ TEST_PAGE,
+ ],
+ expectedPermissionNumber: 1,
+ expects: [
+ [
+ TEST_DOMAIN,
+ TEST_3RD_PARTY_DOMAIN,
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ ],
+ ],
+ },
+ // Tracker1(Interacted) -> Non-Tracker -> Tracker2(Interacted) -> Non-Tracker
+ // Note that the result is not quite correct in this case. We are supposed to
+ // grant access to the least tracker instead of the first one. But, this is
+ // the behavior how we act so far. We would fix this in another bug.
+ {
+ trackersHasUserInteraction: [
+ TEST_3RD_PARTY_DOMAIN,
+ TEST_ANOTHER_3RD_PARTY_DOMAIN_HTTPS,
+ ],
+ redirects: [
+ TEST_TRACKING_REDIRECT_PAGE,
+ TEST_REDIRECT_PAGE,
+ TEST_ANOTHER_TRACKING_REDIRECT_PAGE,
+ TEST_PAGE,
+ ],
+ expectedPermissionNumber: 1,
+ expects: [
+ [
+ TEST_DOMAIN,
+ TEST_3RD_PARTY_DOMAIN,
+ Ci.nsIPermissionManager.ALLOW_ACTION,
+ ],
+ ],
+ },
+ // Tracker(Interacted) -> Non-Tracker (heuristic disabled)
+ {
+ trackersHasUserInteraction: [TEST_3RD_PARTY_DOMAIN],
+ redirects: [TEST_TRACKING_REDIRECT_PAGE, TEST_PAGE],
+ expectedPermissionNumber: 0,
+ expects: [
+ [
+ TEST_DOMAIN,
+ TEST_3RD_PARTY_DOMAIN,
+ Ci.nsIPermissionManager.UNKNOWN_ACTION,
+ ],
+ ],
+ extraPrefs: [["privacy.antitracking.enableWebcompat", false]],
+ },
+];
+
+async function interactWithSpecificTracker(aTracker) {
+ let win = await BrowserTestUtils.openNewBrowserWindow();
+ await BrowserTestUtils.withNewTab(
+ { gBrowser: win.gBrowser, url: aTracker },
+ async function (browser) {
+ info("Let's interact with the tracker");
+
+ await SpecialPowers.spawn(browser, [], async function () {
+ SpecialPowers.wrap(content.document).userInteractionForTesting();
+ });
+ }
+ );
+ await BrowserTestUtils.closeWindow(win);
+}
+
+function getNumberOfStorageAccessPermissions() {
+ let num = 0;
+ for (let perm of Services.perms.all) {
+ if (perm.type.startsWith("3rdPartyStorage^")) {
+ num++;
+ }
+ }
+ return num;
+}
+
+async function verifyStorageAccessPermission(aExpects) {
+ for (let expect of aExpects) {
+ let uri = Services.io.newURI(expect[0]);
+ let principal = Services.scriptSecurityManager.createContentPrincipal(
+ uri,
+ {}
+ );
+ let access = Services.perms.testPermissionFromPrincipal(
+ principal,
+ `3rdPartyStorage^${expect[1].slice(0, -1)}`
+ );
+
+ is(access, expect[2], "The storage access is set correctly");
+ }
+}
+
+add_setup(async function () {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["network.cookie.cookieBehavior", BEHAVIOR_REJECT_TRACKER],
+ ["privacy.trackingprotection.annotate_channels", true],
+ [
+ "privacy.restrict3rdpartystorage.userInteractionRequiredForHosts",
+ "tracking.example.com,tracking.example.org",
+ ],
+ ["privacy.restrict3rdpartystorage.heuristic.redirect", true],
+ ],
+ });
+
+ await UrlClassifierTestUtils.addTestTrackers();
+
+ registerCleanupFunction(_ => {
+ Services.perms.removeAll();
+ });
+});
+
+add_task(async function testETPRedirectHeuristic() {
+ info("Starting testing ETP redirect heuristic ...");
+
+ for (const test of TEST_CASES) {
+ let { extraPrefs } = test;
+ if (extraPrefs) {
+ await SpecialPowers.pushPrefEnv({
+ set: extraPrefs,
+ });
+ }
+
+ // First, clear all permissions.
+ Services.perms.removeAll();
+
+ for (const tracker of test.trackersHasUserInteraction) {
+ info(`Interact with ${tracker} in top-level.`);
+ await interactWithSpecificTracker(tracker);
+ }
+
+ info("Creating a new tab");
+ let tab = BrowserTestUtils.addTab(gBrowser, TEST_PAGE);
+ gBrowser.selectedTab = tab;
+
+ let browser = gBrowser.getBrowserForTab(tab);
+ await BrowserTestUtils.browserLoaded(browser);
+
+ info("Loading the tracking page and trigger the top-level redirect.");
+ SpecialPowers.spawn(browser, [test.redirects], async redirects => {
+ let link = content.document.createElement("a");
+ link.appendChild(content.document.createTextNode("click me!"));
+ link.href = redirects.shift() + "?" + redirects.join("|");
+ content.document.body.appendChild(link);
+ link.click();
+ });
+
+ let finalRedirectDest = test.redirects[test.redirects.length - 1];
+
+ await BrowserTestUtils.browserLoaded(browser, false, finalRedirectDest);
+
+ is(
+ getNumberOfStorageAccessPermissions(),
+ test.expectedPermissionNumber,
+ "The number of storage permissions is correct."
+ );
+
+ await verifyStorageAccessPermission(test.expects);
+
+ info("Removing the tab");
+ BrowserTestUtils.removeTab(tab);
+
+ if (extraPrefs) {
+ await SpecialPowers.popPrefEnv();
+ }
+ }
+});