diff options
Diffstat (limited to 'toolkit/components/antitracking/test/browser/browser_contentBlockingAllowListPrincipal.js')
-rw-r--r-- | toolkit/components/antitracking/test/browser/browser_contentBlockingAllowListPrincipal.js | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/toolkit/components/antitracking/test/browser/browser_contentBlockingAllowListPrincipal.js b/toolkit/components/antitracking/test/browser/browser_contentBlockingAllowListPrincipal.js new file mode 100644 index 0000000000..a9e2ac6fce --- /dev/null +++ b/toolkit/components/antitracking/test/browser/browser_contentBlockingAllowListPrincipal.js @@ -0,0 +1,237 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const TEST_SANDBOX_URL = + "https://example.com/browser/toolkit/components/antitracking/test/browser/sandboxed.html"; + +/** + * Tests the contentBlockingAllowListPrincipal. + * @param {Browser} browser - Browser to test. + * @param {("content"|"system")} type - Expected principal type. + * @param {String} [origin] - Expected origin of principal. Defaults to the + * origin of the browsers content principal. + */ +function checkAllowListPrincipal( + browser, + type, + origin = browser.contentPrincipal.origin +) { + let principal = + browser.browsingContext.currentWindowGlobal + .contentBlockingAllowListPrincipal; + ok(principal, "Principal is set"); + + if (type == "content") { + ok(principal.isContentPrincipal, "Is content principal"); + + ok( + principal.schemeIs("https"), + "allowlist content principal must have https scheme" + ); + } else if (type == "system") { + ok(principal.isSystemPrincipal, "Is system principal"); + } else { + throw new Error("Unexpected principal type"); + } + + is(principal.origin, origin, "Correct origin"); +} + +/** + * Runs a given test in a normal window and in a private browsing window. + * @param {String} initialUrl - URL to load in the initial test tab. + * @param {Function} testCallback - Test function to run in both windows. + */ +async function runTestInNormalAndPrivateMode(initialUrl, testCallback) { + for (let i = 0; i < 2; i++) { + let isPrivateBrowsing = !!i; + info("Running test. Private browsing: " + !!i); + let win = await BrowserTestUtils.openNewBrowserWindow({ + private: isPrivateBrowsing, + }); + let tab = BrowserTestUtils.addTab(win.gBrowser, initialUrl); + let browser = tab.linkedBrowser; + + await BrowserTestUtils.browserLoaded(browser); + + await testCallback(browser, isPrivateBrowsing); + + await BrowserTestUtils.closeWindow(win); + } +} + +/** + * Creates an iframe in the passed browser and waits for it to load. + * @param {Browser} browser - Browser to create the frame in. + * @param {String} src - Frame source url. + * @param {String} id - Frame id. + * @param {String} [sandboxAttr] - Optional list of sandbox attributes to set + * for the iframe. Defaults to no sandbox. + * @returns {Promise} - Resolves once the frame has loaded. + */ +function createFrame(browser, src, id, sandboxAttr) { + return SpecialPowers.spawn( + browser, + [{ page: src, frameId: id, sandboxAttr }], + async function (obj) { + await new content.Promise(resolve => { + let frame = content.document.createElement("iframe"); + frame.src = obj.page; + frame.id = obj.frameId; + if (obj.sandboxAttr) { + frame.setAttribute("sandbox", obj.sandboxAttr); + } + frame.addEventListener("load", resolve, { once: true }); + content.document.body.appendChild(frame); + }); + } + ); +} + +add_task(async setup => { + // Disable heuristics. We don't need them and if enabled the resulting + // telemetry can race with the telemetry in the next test. + // See Bug 1686836, Bug 1686894. + await SpecialPowers.pushPrefEnv({ + set: [ + ["privacy.restrict3rdpartystorage.heuristic.redirect", false], + ["privacy.restrict3rdpartystorage.heuristic.recently_visited", false], + ["privacy.restrict3rdpartystorage.heuristic.window_open", false], + ["dom.security.https_first_pbm", false], + ], + }); +}); + +/** + * Test that we get the correct allow list principal which matches the content + * principal for an https site. + */ +add_task(async test_contentPrincipalHTTPS => { + await runTestInNormalAndPrivateMode("https://example.com", browser => { + checkAllowListPrincipal(browser, "content"); + }); +}); + +/** + * Tests that the scheme of the allowlist principal is HTTPS, even though the + * site is loaded via HTTP. + */ +add_task(async test_contentPrincipalHTTP => { + await runTestInNormalAndPrivateMode( + "http://example.net", + (browser, isPrivateBrowsing) => { + checkAllowListPrincipal( + browser, + "content", + "https://example.net" + + (isPrivateBrowsing ? "^privateBrowsingId=1" : "") + ); + } + ); +}); + +/** + * Tests that the allow list principal is a system principal for the preferences + * about site. + */ +add_task(async test_systemPrincipal => { + await runTestInNormalAndPrivateMode("about:preferences", browser => { + checkAllowListPrincipal(browser, "system"); + }); +}); + +/** + * Tests that we get a valid content principal for top level sandboxed pages, + * and not the document principal which is a null principal. + */ +add_task(async test_TopLevelSandbox => { + await runTestInNormalAndPrivateMode( + TEST_SANDBOX_URL, + (browser, isPrivateBrowsing) => { + ok( + browser.contentPrincipal.isNullPrincipal, + "Top level sandboxed page should have null principal" + ); + checkAllowListPrincipal( + browser, + "content", + "https://example.com" + + (isPrivateBrowsing ? "^privateBrowsingId=1" : "") + ); + } + ); +}); + +/** + * Tests that we get a valid content principal for a new tab opened via + * window.open. + */ +add_task(async test_windowOpen => { + await runTestInNormalAndPrivateMode("https://example.com", async browser => { + checkAllowListPrincipal(browser, "content"); + + let promiseTabOpened = BrowserTestUtils.waitForNewTab( + browser.ownerGlobal.gBrowser, + "https://example.org/", + true + ); + + // Call window.open from iframe. + await SpecialPowers.spawn(browser, [], async function () { + content.open("https://example.org/"); + }); + + let tab = await promiseTabOpened; + + checkAllowListPrincipal(tab.linkedBrowser, "content"); + + BrowserTestUtils.removeTab(tab); + }); +}); + +/** + * Tests that we get a valid content principal for a new tab opened via + * window.open from a sandboxed iframe. + */ +add_task(async test_windowOpenFromSandboxedFrame => { + await runTestInNormalAndPrivateMode( + "https://example.com", + async (browser, isPrivateBrowsing) => { + checkAllowListPrincipal(browser, "content"); + + // Create sandboxed iframe, allow popups. + await createFrame( + browser, + "https://example.com", + "sandboxedIframe", + "allow-popups" + ); + // Iframe BC is the only child of the test browser. + let [frameBrowsingContext] = browser.browsingContext.children; + + let promiseTabOpened = BrowserTestUtils.waitForNewTab( + browser.ownerGlobal.gBrowser, + "https://example.org/", + true + ); + + // Call window.open from iframe. + await SpecialPowers.spawn(frameBrowsingContext, [], async function () { + content.open("https://example.org/"); + }); + + let tab = await promiseTabOpened; + + checkAllowListPrincipal( + tab.linkedBrowser, + "content", + "https://example.org" + + (isPrivateBrowsing ? "^privateBrowsingId=1" : "") + ); + + BrowserTestUtils.removeTab(tab); + } + ); +}); |