From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../test/xpcshell/test_QuarantinedDomains.js | 392 +++++++++++++++++++++ 1 file changed, 392 insertions(+) create mode 100644 toolkit/components/extensions/test/xpcshell/test_QuarantinedDomains.js (limited to 'toolkit/components/extensions/test/xpcshell/test_QuarantinedDomains.js') diff --git a/toolkit/components/extensions/test/xpcshell/test_QuarantinedDomains.js b/toolkit/components/extensions/test/xpcshell/test_QuarantinedDomains.js new file mode 100644 index 0000000000..fdb243150b --- /dev/null +++ b/toolkit/components/extensions/test/xpcshell/test_QuarantinedDomains.js @@ -0,0 +1,392 @@ +"use strict"; + +AddonTestUtils.init(this); +AddonTestUtils.createAppInfo( + "xpcshell@tests.mozilla.org", + "XPCShell", + "1", + "43" +); + +AddonTestUtils.overrideCertDB(); +AddonTestUtils.usePrivilegedSignatures = id => id.startsWith("privileged"); + +add_setup(async () => { + await AddonTestUtils.promiseStartupManager(); +}); + +const server = createHttpServer({ hosts: ["example.org", "example.net"] }); +server.registerPathHandler("/", (request, response) => { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "text/html; charset=utf-8", false); + response.write(""); +}); + +const ADDONS_RESTRICTED_DOMAINS_PREF = + "extensions.webextensions.addons-restricted-domains@mozilla.com.disabled"; + +const DOMAINS = [ + "addons-dev.allizom.org", + "mixed.badssl.com", + "careers.mozilla.com", + "developer.mozilla.org", + "test.example.com", +]; + +const CAN_ACCESS_ALL = DOMAINS.reduce((map, domain) => { + return { ...map, [domain]: true }; +}, {}); + +function makePolicy(options) { + return new WebExtensionPolicy({ + baseURL: "file:///foo/", + localizeCallback: str => str, + allowedOrigins: new MatchPatternSet([""], { ignorePath: true }), + mozExtensionHostname: Services.uuid.generateUUID().toString().slice(1, -1), + ...options, + }); +} + +function makeCS(policy) { + return new WebExtensionContentScript(policy, { + matches: new MatchPatternSet([""]), + }); +} + +function makeExtension({ id }) { + return ExtensionTestUtils.loadExtension({ + manifest: { + browser_specific_settings: { gecko: { id } }, + permissions: [""], + content_scripts: [ + { + js: ["script.js"], + matches: [""], + }, + ], + }, + useAddonManager: "permanent", + files: { + "script.js": ` + browser.test.sendMessage("tld", location.host.split(".").at(-1)); + browser.test.sendMessage("cs"); + `, + }, + }); +} + +function expectQuarantined(expectedDomains) { + for (let domain of DOMAINS) { + let uri = Services.io.newURI(`https://${domain}/`); + let quarantined = expectedDomains.includes(domain); + + equal( + quarantined, + WebExtensionPolicy.isQuarantinedURI(uri), + `Expect ${uri.spec} to ${quarantined ? "" : "not"} be quarantined.` + ); + } +} + +function expectAccess(policy, cs, expected) { + for (let domain of Object.keys(expected)) { + let uri = Services.io.newURI(`https://${domain}/`); + let access = expected[domain]; + let match = access; + + equal( + access, + !policy.quarantinedFromURI(uri), + `${policy.id} is ${access ? "not" : ""} quarantined from ${uri.spec}.` + ); + equal( + access, + policy.canAccessURI(uri), + `Expect ${policy.id} ${access ? "can" : "can't"} access ${uri.spec}.` + ); + + equal( + match, + cs.matchesURI(uri), + `Expect ${cs.extension.id} to ${match ? "" : "not"} match ${uri.spec}.` + ); + } +} + +function expectHost(desc, host, quarantined) { + let uri = Services.io.newURI(`https://${host}/`); + equal( + quarantined, + WebExtensionPolicy.isQuarantinedURI(uri), + `Expect ${desc} "${host}" to ${quarantined ? "" : "not"} be quarantined.` + ); +} + +function makePolicies() { + const plain = makePolicy({ id: "plain@test" }); + const system = makePolicy({ id: "system@test", isPrivileged: true }); + const exempt = makePolicy({ id: "exempt@test", ignoreQuarantine: true }); + + return { plain, system, exempt }; +} + +function makeContentScripts(policies) { + return policies.map(makeCS); +} + +add_task(async function test_QuarantinedDomains() { + const { plain, system, exempt } = makePolicies(); + const [plainCS, systemCS, exemptCS] = makeContentScripts([ + plain, + system, + exempt, + ]); + + info("Initial pref state is an empty list."); + expectQuarantined([]); + + expectAccess(plain, plainCS, CAN_ACCESS_ALL); + expectAccess(system, systemCS, CAN_ACCESS_ALL); + expectAccess(exempt, exemptCS, CAN_ACCESS_ALL); + + info("Default test domain list."); + Services.prefs.setStringPref( + "extensions.quarantinedDomains.list", + "addons-dev.allizom.org,mixed.badssl.com,test.example.com" + ); + + expectQuarantined([ + "addons-dev.allizom.org", + "mixed.badssl.com", + "test.example.com", + ]); + + const EXPECT_DEFAULTS = { + "addons-dev.allizom.org": false, + "mixed.badssl.com": false, + "careers.mozilla.com": true, + "developer.mozilla.org": true, + "test.example.com": false, + }; + + expectAccess(plain, plainCS, EXPECT_DEFAULTS); + expectAccess(system, systemCS, CAN_ACCESS_ALL); + expectAccess(exempt, exemptCS, CAN_ACCESS_ALL); + + info("Test changing policy.ignoreQuarantine after creation."); + + ok(!plain.ignoreQuarantine, "plain policy does not ignore quarantine."); + ok(system.ignoreQuarantine, "system policy does ignore quarantine."); + ok(exempt.ignoreQuarantine, "exempt policy does ignore quarantine."); + + plain.ignoreQuarantine = true; + system.ignoreQuarantine = false; + exempt.ignoreQuarantine = false; + + ok(plain.ignoreQuarantine, "expect plain.ignoreQuarantine to be true."); + ok(!system.ignoreQuarantine, "expect system.ignoreQuarantine to be false."); + ok(!exempt.ignoreQuarantine, "expect exempt.ignoreQuarantine to be false."); + + expectAccess(plain, plainCS, CAN_ACCESS_ALL); + expectAccess(system, systemCS, EXPECT_DEFAULTS); + expectAccess(exempt, exemptCS, EXPECT_DEFAULTS); + + plain.ignoreQuarantine = false; + system.ignoreQuarantine = true; + exempt.ignoreQuarantine = true; + + expectAccess(plain, plainCS, EXPECT_DEFAULTS); + expectAccess(system, systemCS, CAN_ACCESS_ALL); + expectAccess(exempt, exemptCS, CAN_ACCESS_ALL); + + info("Disable the Quarantined Domains feature."); + Services.prefs.setBoolPref("extensions.quarantinedDomains.enabled", false); + expectQuarantined([]); + + expectAccess(plain, plainCS, CAN_ACCESS_ALL); + expectAccess(system, systemCS, CAN_ACCESS_ALL); + expectAccess(exempt, exemptCS, CAN_ACCESS_ALL); + + info( + "Enable again, drop addons-dev.allizom.org and add developer.mozilla.org to the pref." + ); + Services.prefs.setBoolPref("extensions.quarantinedDomains.enabled", true); + + Services.prefs.setStringPref( + "extensions.quarantinedDomains.list", + "mixed.badssl.com,developer.mozilla.org,test.example.com" + ); + expectQuarantined([ + "mixed.badssl.com", + "developer.mozilla.org", + "test.example.com", + ]); + + expectAccess(plain, plainCS, { + "addons-dev.allizom.org": true, + "mixed.badssl.com": false, + "careers.mozilla.com": true, + "developer.mozilla.org": false, + "test.example.com": false, + }); + + expectAccess(system, systemCS, CAN_ACCESS_ALL); + expectAccess(exempt, exemptCS, CAN_ACCESS_ALL); + + expectHost("host with a port", "test.example.com:1025", true); + + expectHost("FQDN", "test.example.com.", false); + expectHost("subdomain", "subdomain.test.example.com", false); + expectHost("domain with prefix", "pretest.example.com", false); + expectHost("domain with suffix", "test.example.comsuf", false); +}); + +function setIgnorePref(id, value = false) { + Services.prefs.setBoolPref(`extensions.quarantineIgnoredByUser.${id}`, value); +} + +// Test that ignore prefs take effect in the content process. +add_task( + { pref_set: [["extensions.quarantinedDomains.list", "example.net"]] }, + async function test_QuarantinedDomains_ignored() { + const EXPECT_DEFAULTS = { "example.org": true, "example.net": false }; + const CAN_ACCESS_ALL = { "example.org": true, "example.net": true }; + + let alpha = makeExtension({ id: "alpha@test" }); + let beta = makeExtension({ id: "beta@test" }); + let system = makeExtension({ id: "privileged@test" }); + + let page = await ExtensionTestUtils.loadContentPage("about:blank"); + + await alpha.startup(); + await beta.startup(); + await system.startup(); + + equal(system.extension.isPrivileged, true, "is privileged"); + + let alphaPolicy = alpha.extension.policy; + let betaPolicy = beta.extension.policy; + + let alphaCounters = { org: 0, net: 0 }; + let betaCounters = { org: 0, net: 0 }; + + alpha.onMessage("tld", tld => alphaCounters[tld]++); + beta.onMessage("tld", tld => betaCounters[tld]++); + system.onMessage("tld", () => {}); + + async function testTLD(tld, expectAlpha, expectBeta) { + let alphaCount = alphaCounters[tld]; + let betaCount = betaCounters[tld]; + + await page.loadURL(`http://example.${tld}/`); + if (expectAlpha) { + await alpha.awaitMessage("cs"); + alphaCount++; + } + if (expectBeta) { + await beta.awaitMessage("cs"); + betaCount++; + } + // Sanity check, plus always having something to await. + await system.awaitMessage("cs"); + + equal(alphaCount, alphaCounters[tld], `Expected ${tld} alpha CS counter`); + equal(betaCount, betaCounters[tld], `Expected ${tld} beta CS counter`); + } + + info("Test defaults, example.org is accessible, example.net is not."); + + await testTLD("org", true, true); + await testTLD("net", false, false); + + expectAccess(alphaPolicy, alphaPolicy.contentScripts[0], EXPECT_DEFAULTS); + expectAccess(betaPolicy, betaPolicy.contentScripts[0], EXPECT_DEFAULTS); + + info("Test setting the pref for alpha@test."); + setIgnorePref("alpha@test", true); + + await testTLD("net", true, false); + await testTLD("org", true, true); + + expectAccess(alphaPolicy, alphaPolicy.contentScripts[0], CAN_ACCESS_ALL); + expectAccess(betaPolicy, betaPolicy.contentScripts[0], EXPECT_DEFAULTS); + + info("Test setting the pref for beta@test."); + setIgnorePref("beta@test", true); + + await testTLD("org", true, true); + await testTLD("net", true, true); + expectAccess(betaPolicy, betaPolicy.contentScripts[0], CAN_ACCESS_ALL); + + info("Test unsetting the pref for alpha@test."); + setIgnorePref("alpha@test", false); + + await testTLD("net", false, true); + await testTLD("org", true, true); + + info("Test unsetting the pref for beta@test."); + setIgnorePref("beta@test", false); + + await testTLD("org", true, true); + await testTLD("net", false, false); + + expectAccess(alphaPolicy, alphaPolicy.contentScripts[0], EXPECT_DEFAULTS); + expectAccess(betaPolicy, betaPolicy.contentScripts[0], EXPECT_DEFAULTS); + + Assert.deepEqual( + alphaCounters, + { org: 5, net: 2 }, + "Expected final Alpha content script counters." + ); + + Assert.deepEqual( + betaCounters, + { org: 5, net: 2 }, + "Expected final Beta content script counters." + ); + + await system.unload(); + await beta.unload(); + await alpha.unload(); + + await page.close(); + } +); + +// Make sure we honor the system add-on pref. +add_task( + { + pref_set: [ + [ADDONS_RESTRICTED_DOMAINS_PREF, true], + [ + "extensions.quarantinedDomains.list", + "addons-dev.allizom.org,mixed.badssl.com,test.example.com", + ], + ], + }, + async function test_QuarantinedDomains_with_system_addon_disabled() { + await AddonTestUtils.promiseRestartManager(); + + const { plain, system, exempt } = makePolicies(); + const [plainCS, systemCS, exemptCS] = makeContentScripts([ + plain, + system, + exempt, + ]); + + expectQuarantined([]); + expectAccess(plain, plainCS, CAN_ACCESS_ALL); + expectAccess(system, systemCS, CAN_ACCESS_ALL); + expectAccess(exempt, exemptCS, CAN_ACCESS_ALL); + + // When the user changes this pref to re-enable the system add-on... + Services.prefs.setBoolPref(ADDONS_RESTRICTED_DOMAINS_PREF, false); + // ...after a AOM restart... + await AddonTestUtils.promiseRestartManager(); + // ...we expect no change. + expectQuarantined([]); + expectAccess(plain, plainCS, CAN_ACCESS_ALL); + expectAccess(system, systemCS, CAN_ACCESS_ALL); + expectAccess(exempt, exemptCS, CAN_ACCESS_ALL); + } +); -- cgit v1.2.3