Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

/* Any copyright is dedicated to the Public Domain.
"use strict";
ChromeUtils.defineESModuleGetters(this, {
ContentBlockingAllowList:
"resource://gre/modules/ContentBlockingAllowList.sys.mjs",
});
const TEST_SANDBOX_URL =
/**
* 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 () => {
// Disable heuristics. We don't need them and if enabled the resulting
// telemetry can race with the telemetry in the next test.
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 () => {
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 () => {
await runTestInNormalAndPrivateMode(
(browser, isPrivateBrowsing) => {
checkAllowListPrincipal(
browser,
"content",
(isPrivateBrowsing ? "^privateBrowsingId=1" : "")
);
}
);
});
/**
* Tests that the allow list principal is a system principal for the preferences
* about site.
*/
add_task(async () => {
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 () => {
await runTestInNormalAndPrivateMode(
TEST_SANDBOX_URL,
(browser, isPrivateBrowsing) => {
ok(
browser.contentPrincipal.isNullPrincipal,
"Top level sandboxed page should have null principal"
);
checkAllowListPrincipal(
browser,
"content",
(isPrivateBrowsing ? "^privateBrowsingId=1" : "")
);
}
);
});
/**
* Tests that we get a valid content principal for a new tab opened via
* window.open.
*/
add_task(async () => {
await runTestInNormalAndPrivateMode("https://example.com", async browser => {
checkAllowListPrincipal(browser, "content");
let promiseTabOpened = BrowserTestUtils.waitForNewTab(
browser.ownerGlobal.gBrowser,
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 () => {
await runTestInNormalAndPrivateMode(
async (browser, isPrivateBrowsing) => {
checkAllowListPrincipal(browser, "content");
// Create sandboxed iframe, allow popups.
await createFrame(
browser,
"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,
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",
(isPrivateBrowsing ? "^privateBrowsingId=1" : "")
);
BrowserTestUtils.removeTab(tab);
}
);
});
/**
* Tests that the usingStorageAccess flag is correctly set for window contexts
* when the content blocking allow list is set.
*/
add_task(async () => {
// Add content blocking allow list exception for example.com in both normal
// and private mode.
let tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
);
ContentBlockingAllowList.add(tab.linkedBrowser);
BrowserTestUtils.removeTab(tab);
// Creating a private window to add the content blocking allow list exception
// for example.com. Note that we need to keep the private window opened to
// keep the allow list exception alive.
let privateWin = await BrowserTestUtils.openNewBrowserWindow({
private: true,
});
let privateTab = await BrowserTestUtils.openNewForegroundTab(
privateWin.gBrowser,
);
ContentBlockingAllowList.add(privateTab.linkedBrowser);
BrowserTestUtils.removeTab(privateTab);
await runTestInNormalAndPrivateMode(
async (browser, _) => {
// Check the usingStorageAccess flag of the top level window context. It
// should always be false.
ok(
!browser.browsingContext.currentWindowGlobal.usingStorageAccess,
"The usingStorageAccess flag should be false for the top-level context"
);
// Create a third-party iframe.
await createFrame(browser, "https://example.org", "iframe");
// Iframe BC is the only child of the test browser.
let [frameBrowsingContext] = browser.browsingContext.children;
// Check the usingStorageAccess flag of the iframe's window context. It
// should be true.
ok(
frameBrowsingContext.currentWindowGlobal.usingStorageAccess,
"The usingStorageAccess flag should be true for the iframe's context"
);
// Create a ABA iframe.
await createFrame(
frameBrowsingContext,
"ABAiframe"
);
// ABA iframe is the only child of the iframe BC.
let [abaFrameBrowsingContext] = frameBrowsingContext.children;
// Check the usingStorageAccess flag of the ABA iframe's window context.
// It should be true.
ok(
abaFrameBrowsingContext.currentWindowGlobal.usingStorageAccess,
"The usingStorageAccess flag should be true for the ABA iframe's context"
);
// Clean the content blocking allow list.
ContentBlockingAllowList.remove(browser);
}
);
await BrowserTestUtils.closeWindow(privateWin);
});