Skip to content

Commit

Permalink
Bug 1839919 - Add tests for persistence and OA separation. r=bvanders…
Browse files Browse the repository at this point in the history
…loot,anti-tracking-reviewers

Differential Revision: https://phabricator.services.mozilla.com/D200821
  • Loading branch information
Trikolon committed Feb 14, 2024
1 parent f2ff1ef commit 1fb6fc2
Show file tree
Hide file tree
Showing 5 changed files with 322 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ support-files = [
"file_bounce.html",
]

["browser_bouncetracking_oa_isolation.js"]

["browser_bouncetracking_purge.js"]

["browser_bouncetracking_simple.js"]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

add_setup(async function () {
await SpecialPowers.pushPrefEnv({
set: [
["privacy.bounceTrackingProtection.requireStatefulBounces", true],
["privacy.bounceTrackingProtection.bounceTrackingGracePeriodSec", 0],
],
});
});

// Tests that bounces in PBM don't affect state in normal browsing.
add_task(async function test_pbm_data_isolated() {
await runTestBounce({
bounceType: "client",
setState: "cookie-client",
originAttributes: { privateBrowsingId: 1 },
postBounceCallback: () => {
// After the PBM bounce assert that we haven't recorded any data for normal browsing.
Assert.equal(
bounceTrackingProtection.testGetBounceTrackerCandidateHosts({}).length,
0,
"No bounce tracker candidates for normal browsing."
);
Assert.equal(
bounceTrackingProtection.testGetUserActivationHosts({}).length,
0,
"No user activations for normal browsing."
);
},
});
});

// Tests that bounces in PBM don't affect state in normal browsing.
add_task(async function test_containers_isolated() {
await runTestBounce({
bounceType: "server",
setState: "cookie-server",
originAttributes: { userContextId: 2 },
postBounceCallback: () => {
// After the bounce in the container tab assert that we haven't recorded any data for normal browsing.
Assert.equal(
bounceTrackingProtection.testGetBounceTrackerCandidateHosts({}).length,
0,
"No bounce tracker candidates for normal browsing."
);
Assert.equal(
bounceTrackingProtection.testGetUserActivationHosts({}).length,
0,
"No user activations for normal browsing."
);

// Or in another container tab.
Assert.equal(
bounceTrackingProtection.testGetBounceTrackerCandidateHosts({
userContextId: 1,
}).length,
0,
"No bounce tracker candidates for container tab 1."
);
Assert.equal(
bounceTrackingProtection.testGetUserActivationHosts({
userContextId: 1,
}).length,
0,
"No user activations for container tab 1."
);
},
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -145,75 +145,131 @@ async function waitForRecordBounces(browser) {
* identified as a bounce tracker (candidate).
* @param {boolean} [options.expectPurge=true] - Expect the redirecting site to have
* its storage purged.
* @param {OriginAttributes} [options.originAttributes={}] - Origin attributes
* to use for the test. This determines whether the test is run in normal
* browsing, a private window or a container tab. By default the test is run
* in normal browsing.
* @param {function} [options.postBounceCallback] - Optional function to run after the
* bounce has completed.
*/
async function runTestBounce(options = {}) {
let {
bounceType,
setState = null,
expectCandidate = true,
expectPurge = true,
originAttributes = {},
postBounceCallback = () => {},
} = options;
info(`runTestBounce ${JSON.stringify(options)}`);

Assert.equal(
bounceTrackingProtection.testGetBounceTrackerCandidateHosts({}).length,
bounceTrackingProtection.testGetBounceTrackerCandidateHosts(
originAttributes
).length,
0,
"No bounce tracker hosts initially."
);
Assert.equal(
bounceTrackingProtection.testGetUserActivationHosts({}).length,
bounceTrackingProtection.testGetUserActivationHosts(originAttributes)
.length,
0,
"No user activation hosts initially."
);

await BrowserTestUtils.withNewTab(
getBaseUrl(ORIGIN_A) + "file_start.html",
async browser => {
let promiseRecordBounces = waitForRecordBounces(browser);

// The final destination after the bounce.
let targetURL = new URL(getBaseUrl(ORIGIN_B) + "file_start.html");

// Navigate through the bounce chain.
await navigateLinkClick(
browser,
getBounceURL({ bounceType, targetURL, setState })
);

// Wait for the final site to be loaded which complete the BounceTrackingRecord.
await BrowserTestUtils.browserLoaded(browser, false, targetURL);

// 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(
browser,
new URL(getBaseUrl(ORIGIN_C) + "file_start.html")
);

await promiseRecordBounces;

Assert.deepEqual(
bounceTrackingProtection.testGetBounceTrackerCandidateHosts({}),
expectCandidate ? [SITE_TRACKER] : [],
`Should ${
expectCandidate ? "" : "not "
}have identified ${SITE_TRACKER} as a bounce tracker.`
);
Assert.deepEqual(
bounceTrackingProtection.testGetUserActivationHosts({}).sort(),
[SITE_A, SITE_B].sort(),
"Should only have user activation for sites where we clicked links."
);

Assert.deepEqual(
await bounceTrackingProtection.testRunPurgeBounceTrackers(),
expectPurge ? [SITE_TRACKER] : [],
`Should ${expectPurge ? "" : "not "}purge state for ${SITE_TRACKER}.`
);

bounceTrackingProtection.reset();
}
let win = window;
let { privateBrowsingId, userContextId } = originAttributes;
let usePrivateWindow =
privateBrowsingId != null &&
privateBrowsingId !=
Services.scriptSecurityManager.DEFAULT_PRIVATE_BROWSING_ID;
if (userContextId != null && userContextId > 0 && usePrivateWindow) {
throw new Error("userContextId is not supported in private windows");
}

if (usePrivateWindow) {
win = await BrowserTestUtils.openNewBrowserWindow({ private: true });
}

let tab = win.gBrowser.addTab(getBaseUrl(ORIGIN_A) + "file_start.html", {
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
userContextId,
});
win.gBrowser.selectedTab = tab;

let browser = tab.linkedBrowser;
await BrowserTestUtils.browserLoaded(browser);

let promiseRecordBounces = waitForRecordBounces(browser);

// The final destination after the bounce.
let targetURL = new URL(getBaseUrl(ORIGIN_B) + "file_start.html");

// Navigate through the bounce chain.
await navigateLinkClick(
browser,
getBounceURL({ bounceType, targetURL, setState })
);

// Wait for the final site to be loaded which complete the BounceTrackingRecord.
await BrowserTestUtils.browserLoaded(browser, false, targetURL);

// 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(
browser,
new URL(getBaseUrl(ORIGIN_C) + "file_start.html")
);

await promiseRecordBounces;

Assert.deepEqual(
bounceTrackingProtection.testGetBounceTrackerCandidateHosts(
originAttributes
),
expectCandidate ? [SITE_TRACKER] : [],
`Should ${
expectCandidate ? "" : "not "
}have identified ${SITE_TRACKER} as a bounce tracker.`
);
Assert.deepEqual(
bounceTrackingProtection
.testGetUserActivationHosts(originAttributes)
.sort(),
[SITE_A, SITE_B].sort(),
"Should only have user activation for sites where we clicked links."
);

// If the caller specified a function to run after the bounce, run it now.
await postBounceCallback();

Assert.deepEqual(
await bounceTrackingProtection.testRunPurgeBounceTrackers(),
expectPurge ? [SITE_TRACKER] : [],
`Should ${expectPurge ? "" : "not "}purge state for ${SITE_TRACKER}.`
);

// Clean up
BrowserTestUtils.removeTab(tab);
if (usePrivateWindow) {
await BrowserTestUtils.closeWindow(win);

info(
"Closing the last PBM window should trigger a purge of all PBM state."
);
Assert.ok(
!bounceTrackingProtection.testGetBounceTrackerCandidateHosts(
originAttributes
).length,
"No bounce tracker hosts after closing private window."
);
Assert.ok(
!bounceTrackingProtection.testGetUserActivationHosts(originAttributes)
.length,
"No user activation hosts after closing private window."
);
}
bounceTrackingProtection.reset();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[DEFAULT]
prefs = [
"privacy.bounceTrackingProtection.enabled=true",
"privacy.bounceTrackingProtection.enableTestMode=true",
]

["test_bouncetracking_storage_persistence.py"]
Loading

0 comments on commit 1fb6fc2

Please sign in to comment.