summaryrefslogtreecommitdiffstats
path: root/toolkit/components/antitracking/bouncetrackingprotection/test/browser/browser_bouncetracking_popup.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/antitracking/bouncetrackingprotection/test/browser/browser_bouncetracking_popup.js')
-rw-r--r--toolkit/components/antitracking/bouncetrackingprotection/test/browser/browser_bouncetracking_popup.js126
1 files changed, 126 insertions, 0 deletions
diff --git a/toolkit/components/antitracking/bouncetrackingprotection/test/browser/browser_bouncetracking_popup.js b/toolkit/components/antitracking/bouncetrackingprotection/test/browser/browser_bouncetracking_popup.js
new file mode 100644
index 0000000000..9e6fa8caf1
--- /dev/null
+++ b/toolkit/components/antitracking/bouncetrackingprotection/test/browser/browser_bouncetracking_popup.js
@@ -0,0 +1,126 @@
+/* Any copyright is dedicated to the Public Domain.
+ https://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+let bounceTrackingProtection;
+
+add_setup(async function () {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["privacy.bounceTrackingProtection.requireStatefulBounces", true],
+ ["privacy.bounceTrackingProtection.bounceTrackingGracePeriodSec", 0],
+ ],
+ });
+ bounceTrackingProtection = Cc[
+ "@mozilla.org/bounce-tracking-protection;1"
+ ].getService(Ci.nsIBounceTrackingProtection);
+});
+
+async function runTest(spawnWindowType) {
+ if (!spawnWindowType || !["newTab", "popup"].includes(spawnWindowType)) {
+ throw new Error(`Invalid option '${spawnWindowType}' for spawnWindowType`);
+ }
+
+ Assert.equal(
+ bounceTrackingProtection.testGetBounceTrackerCandidateHosts({}).length,
+ 0,
+ "No bounce tracker hosts initially."
+ );
+ Assert.equal(
+ bounceTrackingProtection.testGetUserActivationHosts({}).length,
+ 0,
+ "No user activation hosts initially."
+ );
+
+ // Spawn a tab with A, the start of the bounce chain.
+ await BrowserTestUtils.withNewTab(
+ getBaseUrl(ORIGIN_A) + "file_start.html",
+ async browser => {
+ // The destination site C to navigate to after the bounce.
+ let finalURL = new URL(getBaseUrl(ORIGIN_B) + "file_start.html");
+ // The middle hop in the bounce chain B that redirects to finalURL C.
+ let bounceURL = getBounceURL({
+ bounceType: "client",
+ targetURL: finalURL,
+ setState: "cookie-client",
+ });
+
+ // Register a promise for the new popup window. This resolves once the popup
+ // has opened and the final url (C) has been loaded.
+ let openPromise;
+
+ if (spawnWindowType == "newTab") {
+ openPromise = BrowserTestUtils.waitForNewTab(gBrowser, finalURL.href);
+ } else {
+ openPromise = BrowserTestUtils.waitForNewWindow({ url: finalURL.href });
+ }
+
+ // Navigate through the bounce chain by opening a popup to the bounce URL.
+ await navigateLinkClick(browser, bounceURL, {
+ spawnWindow: spawnWindowType,
+ });
+
+ let tabOrWindow = await openPromise;
+
+ let tabOrWindowBrowser;
+ if (spawnWindowType == "newTab") {
+ tabOrWindowBrowser = tabOrWindow.linkedBrowser;
+ } else {
+ tabOrWindowBrowser = tabOrWindow.gBrowser.selectedBrowser;
+ }
+
+ let promiseRecordBounces = waitForRecordBounces(tabOrWindowBrowser);
+
+ // Navigate again with user gesture which triggers
+ // BounceTrackingProtection::RecordStatefulBounces. We could rely on the
+ // timeout (mClientBounceDetectionTimeout) here but that can cause races
+ // in debug where the load is quite slow.
+ await navigateLinkClick(
+ tabOrWindowBrowser,
+ new URL(getBaseUrl(ORIGIN_C) + "file_start.html")
+ );
+
+ info("Wait for bounce trackers to be recorded.");
+ await promiseRecordBounces;
+
+ // Cleanup popup or tab.
+ if (spawnWindowType == "newTab") {
+ await BrowserTestUtils.removeTab(tabOrWindow);
+ } else {
+ await BrowserTestUtils.closeWindow(tabOrWindow);
+ }
+ }
+ );
+
+ // Check that the bounce tracker was detected.
+ Assert.deepEqual(
+ bounceTrackingProtection
+ .testGetBounceTrackerCandidateHosts({})
+ .map(entry => entry.siteHost),
+ [SITE_TRACKER],
+ "Bounce tracker in popup detected."
+ );
+
+ // Cleanup.
+ bounceTrackingProtection.clearAll();
+ await SiteDataTestUtils.clear();
+}
+
+/**
+ * Tests that bounce trackers which use popups as the first hop in the bounce
+ * chain can not bypass detection.
+ *
+ * A -> popup -> B -> C
+ *
+ * A opens a popup and loads B in it. B is the tracker that performs a
+ * short-lived redirect and C is the final destination.
+ */
+
+add_task(async function test_popup() {
+ await runTest("popup");
+});
+
+add_task(async function test_new_tab() {
+ await runTest("newTab");
+});