Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
/* Any copyright is dedicated to the Public Domain.
"use strict";
/**
* Tests that IPv6 addresses are correctly handled by bounce tracking
* protection, with the address stored with brackets in the candidate
* and user activation lists.
*/
const { HttpServer } = ChromeUtils.importESModule(
);
let defined = {};
ChromeUtils.defineLazyGetter(defined, "IPV6_ORIGIN", function () {
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
return `http://[::1]:${gHttpServer.identity.primaryPort}`;
});
let gHttpServer;
let bounceTrackingProtection;
add_setup(async function () {
bounceTrackingProtection = Cc[
"@mozilla.org/bounce-tracking-protection;1"
].getService(Ci.nsIBounceTrackingProtection);
await SpecialPowers.pushPrefEnv({
set: [
[
"privacy.bounceTrackingProtection.mode",
Ci.nsIBounceTrackingProtection.MODE_ENABLED,
],
["privacy.bounceTrackingProtection.requireStatefulBounces", false],
["privacy.bounceTrackingProtection.bounceTrackingGracePeriodSec", 0],
],
});
gHttpServer = new HttpServer();
// Handler that serves a simple HTML page.
gHttpServer.registerPathHandler("/", (request, response) => {
response.setStatusLine(request.httpVersion, 200, "OK");
response.setHeader("Content-Type", "text/html", false);
response.write(
'<!DOCTYPE html><html><body><a id="link" href="#">click</a></body></html>'
);
});
// Handler that performs a server-side redirect.
gHttpServer.registerPathHandler("/bounce", (request, response) => {
let target = request.queryString.split("=")[1];
response.setStatusLine(request.httpVersion, 302, "Found");
response.setHeader("Location", decodeURIComponent(target), false);
});
gHttpServer._start(-1, "[::1]");
registerCleanupFunction(async () => {
await gHttpServer.stop();
bounceTrackingProtection.clearAll();
});
});
add_task(async function test_ipv6_bounce_tracker() {
info("Test that an IPv6 bounce tracker is recorded with brackets.");
bounceTrackingProtection.clearAll();
Assert.equal(
bounceTrackingProtection.testGetBounceTrackerCandidateHosts({}).length,
0,
"No bounce tracker candidates initially."
);
Assert.equal(
bounceTrackingProtection.testGetUserActivationHosts({}).length,
0,
"No user activation hosts initially."
);
let finalUrl = getBaseUrl(ORIGIN_B) + "file_start.html";
await BrowserTestUtils.withNewTab(
getBaseUrl(ORIGIN_A) + "file_start.html",
async browser => {
let promiseRecordBounces = waitForRecordBounces(browser);
// Construct a bounce URL that goes through the IPv6 server.
let bounceUrl = `${defined.IPV6_ORIGIN}/bounce?target=${encodeURIComponent(finalUrl)}`;
info(`Navigating through IPv6 bounce: ${bounceUrl}`);
// Navigate through the IPv6 bounce.
await navigateLinkClick(browser, new URL(bounceUrl));
// Wait for the final destination to load.
await BrowserTestUtils.browserLoaded(browser, false, finalUrl);
// Trigger end of extended navigation by navigating with user gesture.
await navigateLinkClick(
browser,
new URL(getBaseUrl(ORIGIN_C) + "file_start.html")
);
await promiseRecordBounces;
info("Checking bounce tracker candidates.");
let candidateHosts = bounceTrackingProtection
.testGetBounceTrackerCandidateHosts({})
.map(entry => entry.siteHost);
Assert.deepEqual(
candidateHosts,
["[::1]"],
"IPv6 bounce tracker should be recorded with brackets."
);
info("Checking user activation hosts.");
let userActivationHosts = bounceTrackingProtection
.testGetUserActivationHosts({})
.map(entry => entry.siteHost)
.sort();
Assert.deepEqual(
userActivationHosts,
[SITE_A, SITE_B].sort(),
"User activation should be recorded for sites with user interaction."
);
}
);
bounceTrackingProtection.clearAll();
});
add_task(async function test_ipv6_user_activation() {
info("Test that user activation on an IPv6 site is recorded with brackets.");
bounceTrackingProtection.clearAll();
Assert.equal(
bounceTrackingProtection.testGetUserActivationHosts({}).length,
0,
"No user activation hosts initially."
);
await BrowserTestUtils.withNewTab(
`${defined.IPV6_ORIGIN}/`,
async browser => {
info("Simulating user interaction on the IPv6 page.");
await BrowserTestUtils.synthesizeMouseAtPoint(1, 1, {}, browser);
}
);
info("Checking user activation hosts.");
let userActivationHosts = bounceTrackingProtection
.testGetUserActivationHosts({})
.map(entry => entry.siteHost);
Assert.deepEqual(
userActivationHosts,
["[::1]"],
"IPv6 user activation should be recorded with brackets."
);
bounceTrackingProtection.clearAll();
});