summaryrefslogtreecommitdiffstats
path: root/toolkit/components/extensions/test/xpcshell/test_ext_webRequest_restrictedHeaders.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /toolkit/components/extensions/test/xpcshell/test_ext_webRequest_restrictedHeaders.js
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/extensions/test/xpcshell/test_ext_webRequest_restrictedHeaders.js')
-rw-r--r--toolkit/components/extensions/test/xpcshell/test_ext_webRequest_restrictedHeaders.js252
1 files changed, 252 insertions, 0 deletions
diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_webRequest_restrictedHeaders.js b/toolkit/components/extensions/test/xpcshell/test_ext_webRequest_restrictedHeaders.js
new file mode 100644
index 0000000000..471bae0493
--- /dev/null
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_webRequest_restrictedHeaders.js
@@ -0,0 +1,252 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+Services.prefs.setBoolPref("extensions.manifestV3.enabled", true);
+
+AddonTestUtils.init(this);
+AddonTestUtils.createAppInfo(
+ "xpcshell@tests.mozilla.org",
+ "XPCShell",
+ "1",
+ "43"
+);
+
+const server = createHttpServer({
+ hosts: ["example.net"],
+});
+server.registerPathHandler("/test/response-header", (req, res) => {
+ let headerName;
+ let headerValue;
+ if (req.queryString) {
+ let params = new URLSearchParams(req.queryString);
+ headerName = params.get("name");
+ headerValue = params.get("value");
+ res.setHeader(headerName, headerValue, false);
+ res.setHeader("test", `${headerName}=${headerValue}`, false);
+ }
+ res.write("");
+});
+
+const extensionData = {
+ useAddonManager: "temporary",
+ background() {
+ const { manifest_version } = browser.runtime.getManifest();
+ let headerToSet = undefined;
+ browser.test.onMessage.addListener(function (msg, arg) {
+ if (msg !== "header-to-set") {
+ return;
+ }
+ headerToSet = arg;
+ browser.test.sendMessage("header-to-set:done");
+ });
+ browser.webRequest.onHeadersReceived.addListener(
+ e => {
+ browser.test.log(`onHeadersReceived ${e.requestId} ${e.url}`);
+ if (headerToSet === undefined) {
+ browser.test.fail(
+ "extension called before headerToSet option was set"
+ );
+ }
+ if (typeof headerToSet?.name == "string") {
+ const existingHeader = e.responseHeaders.filter(
+ i => i.name.toLowerCase() === headerToSet.name
+ )[0];
+ e.responseHeaders = e.responseHeaders.filter(
+ i => i.name.toLowerCase() != headerToSet.name
+ );
+ // Omit the header if the value isn't set, change the header otherwise.
+ if (headerToSet.value != null) {
+ e.responseHeaders.push({
+ name: headerToSet.name,
+ value: headerToSet.value,
+ });
+ }
+ browser.test.log(
+ `Test Extension MV${manifest_version} (${browser.runtime.id}) sets responseHeader: "${headerToSet.name}"="${headerToSet.value}" (was originally set to "${existingHeader?.value})"`
+ );
+ }
+ return { responseHeaders: e.responseHeaders };
+ },
+ { urls: ["*://example.net/test/*"] },
+ ["blocking", "responseHeaders"]
+ );
+ browser.webRequest.onCompleted.addListener(
+ e => {
+ browser.test.log(`onCompletedReceived ${e.requestId} ${e.url}`);
+ const responseHeaders = e.responseHeaders.filter(
+ i => i.name.toLowerCase() === headerToSet.name
+ );
+
+ browser.test.sendMessage(
+ "on-completed:response-headers",
+ responseHeaders
+ );
+ },
+ { urls: ["*://example.net/test/*"] },
+ ["responseHeaders"]
+ );
+ browser.test.sendMessage("bgpage:ready");
+ },
+};
+
+const extDataMV2 = {
+ ...extensionData,
+ manifest: {
+ manifest_version: 2,
+ permissions: ["webRequest", "webRequestBlocking", "*://example.net/test/*"],
+ },
+};
+
+const extDataMV3 = {
+ ...extensionData,
+ manifest: {
+ manifest_version: 3,
+ permissions: ["webRequest", "webRequestBlocking"],
+ host_permissions: ["*://example.net/test/*"],
+ granted_host_permissions: true,
+ },
+};
+
+add_setup(async () => {
+ await AddonTestUtils.promiseStartupManager();
+});
+
+async function test_restricted_response_headers_changes({
+ firstExtData,
+ secondExtData,
+ headerName,
+ firstExtHeaderChange,
+ secondExtHeaderChange,
+ siteHeaderValue,
+ expectedHeaderValue,
+}) {
+ const ext1 = ExtensionTestUtils.loadExtension(firstExtData);
+ const ext2 = secondExtData && ExtensionTestUtils.loadExtension(secondExtData);
+
+ await ext1.startup();
+ await ext1.awaitMessage("bgpage:ready");
+
+ await ext2?.startup();
+ await ext2?.awaitMessage("bgpage:ready");
+
+ ext1.sendMessage("header-to-set", {
+ name: headerName,
+ value: firstExtHeaderChange,
+ });
+ await ext1.awaitMessage("header-to-set:done");
+ ext2?.sendMessage("header-to-set", {
+ name: headerName,
+ value: secondExtHeaderChange,
+ });
+ await ext2?.awaitMessage("header-to-set:done");
+
+ if (siteHeaderValue) {
+ await ExtensionTestUtils.fetch(
+ "http://example.net/",
+ `http://example.net/test/response-header?name=${headerName}&value=${siteHeaderValue}`
+ );
+ } else {
+ await ExtensionTestUtils.fetch(
+ "http://example.net/",
+ "http://example.net/test/response-header"
+ );
+ }
+
+ const [finalSiteHeaders] = await Promise.all([
+ ext1.awaitMessage("on-completed:response-headers"),
+ ext2?.awaitMessage("on-completed:response-headers"),
+ ]);
+
+ Assert.deepEqual(
+ finalSiteHeaders,
+ expectedHeaderValue
+ ? [{ name: headerName, value: expectedHeaderValue }]
+ : [],
+ "Got the expected response header"
+ );
+
+ await ext1.unload();
+ await ext2?.unload();
+}
+
+add_task(async function test_changes_to_restricted_response_headers() {
+ const testCases = [
+ {
+ headerName: "cross-origin-embedder-policy",
+ siteHeaderValue: "require-corp",
+ firstExtHeaderChange: "credentialless",
+ secondExtHeaderChange: "unsafe-none",
+ },
+ {
+ headerName: "cross-origin-opener-policy",
+ siteHeaderValue: "same-origin",
+ firstExtHeaderChange: "same-origin-allow-popups",
+ secondExtHeaderChange: "unsafe-none",
+ },
+ {
+ headerName: "cross-origin-resource-policy",
+ siteHeaderValue: "same-origin",
+ firstExtHeaderChange: "same-site",
+ secondExtHeaderChange: "cross-origin",
+ },
+ {
+ headerName: "x-frame-options",
+ siteHeaderValue: "deny",
+ firstExtHeaderChange: "sameorigin",
+ secondExtHeaderChange: "allow-from=http://example.com",
+ },
+ {
+ headerName: "access-control-allow-credentials",
+ siteHeaderValue: "true",
+ firstExtHeaderChange: "false",
+ secondExtHeaderChange: "false",
+ },
+ {
+ headerName: "access-control-allow-methods",
+ siteHeaderValue: "*",
+ firstExtHeaderChange: "",
+ secondExtHeaderChange: "GET",
+ },
+ ];
+
+ for (const testCase of testCases) {
+ info(
+ `Test MV3 extension disallowed to change restricted header if already set by the website: "${testCase.headerName}"="${testCase.siteHeaderValue}`
+ );
+ await test_restricted_response_headers_changes({
+ ...testCase,
+ firstExtData: extDataMV3,
+ // Expect the value set by the server to be preserved.
+ expectedHeaderValue: testCase.siteHeaderValue,
+ });
+ }
+
+ for (const testCase of testCases) {
+ info(
+ `Test MV3 extension disallowed to change restricted header also if not set by the website: "${testCase.headerName}`
+ );
+ await test_restricted_response_headers_changes({
+ ...testCase,
+ siteHeaderValue: null,
+ firstExtData: extDataMV3,
+ // Expect the value set by the server to be preserved.
+ expectedHeaderValue: null,
+ });
+ }
+
+ for (const testCase of testCases) {
+ info(
+ `Test MV2 extension allowed to change restricted header if already set by the website: ${JSON.stringify(
+ testCase.siteHeader
+ )}`
+ );
+ await test_restricted_response_headers_changes({
+ ...testCase,
+ firstExtData: extDataMV3,
+ secondExtData: extDataMV2,
+ // Expect the value set by the server to be preserved.
+ expectedHeaderValue: testCase.secondExtHeaderChange,
+ });
+ }
+});