Bug 1897759 - Don't run content scripts at view-source r=rpl

Differential Revision: https://phabricator.services.mozilla.com/D211255
This commit is contained in:
Rob Wu 2024-05-23 11:00:32 +00:00
parent 151da9941c
commit 506a8ebb42
3 changed files with 62 additions and 2 deletions

View file

@ -100,8 +100,14 @@ DEFINE_STATIC_ATOM_SET(WildcardSchemes, nsGkAtoms::http, nsGkAtoms::https,
// usually equal to the origin component of such URLs.
// Counter-examples: about: and data: do not have any embedded origin,
// blob:-URLs have an origin (becomes "null" when opaque) and no path.
//
// Note: view-source: is part of this set to make sure that we always look at
// the URL and never at the principal in these cases, because in case of null
// principals, the precursor could be a http(s) URL. We don't want to run
// scripts in view-source: because we have historically not allowed extensions
// to do so.
DEFINE_STATIC_ATOM_SET(NonOpaqueSchemes, nsGkAtoms::http, nsGkAtoms::https,
nsGkAtoms::file);
nsGkAtoms::file, nsGkAtoms::view_source);
#undef DEFINE_STATIC_ATOM_SET

View file

@ -19,13 +19,15 @@
*/
const server = createHttpServer({ hosts: ["example.com"] });
let gRequestCount = 0;
server.registerPathHandler("/dummy", (request, response) => {
++gRequestCount;
response.setStatusLine(request.httpVersion, 200, "OK");
// The test will add iframes.
response.write("(dummy, no iframes from server)");
});
server.registerPathHandler("/sandboxed", (request, response) => {
++gRequestCount;
response.setStatusLine(request.httpVersion, 200, "OK");
response.setHeader("Content-Security-Policy", "sandbox allow-scripts;");
response.write("This page has an opaque origin.");
@ -684,3 +686,54 @@ add_task(async function test_preload_at_data_url() {
await contentPage.close();
await extension.unload();
});
// No execution nor preload for content scripts at view-source:-URLs.
add_task(async function test_no_preload_nor_execution_at_view_source() {
let extension = ExtensionTestUtils.loadExtension({
manifest: {
content_scripts: [
{
matches: ["*://example.com/*"],
match_origin_as_fallback: true,
js: ["done.js"],
run_at: "document_start",
},
],
},
files: {
"done.js": `browser.test.fail("Unexpected:: " + origin + document.URL);`,
},
});
await extension.startup();
gRequestCount = 0;
// Load initial view-source to get the right process.
let contentPage = await ExtensionTestUtils.loadContentPage(
"view-source:http://example.com/dummy?initial-viewSource"
);
await ensureContentScriptDetector(extension, contentPage);
// Since we are not expecting content script execution, there is no event to
// wait for, so we just load another page to maximize the chance of catching
// an unexpected content script, if any.
await contentPage.loadURL("view-source:http://example.com/dummy?viewSource");
// Also test sandboxed origins (regression test for bug 1897759).
await contentPage.loadURL("view-source:http://example.com/sandboxed?viewS1");
// Call ensureContentScriptDetector() again to make sure that we can detect
// content scripts even if sandboxed origins somehow get their own process.
await ensureContentScriptDetector(extension, contentPage);
await contentPage.loadURL("view-source:http://example.com/sandboxed?viewS2");
Assert.equal(gRequestCount, 4, "Got two view-source requests.");
gRequestCount = 0;
Assert.deepEqual(
await getSeenContentScriptInjections(extension, contentPage),
undefined,
"Should not have observed any content scripts at view-source:-URLs"
);
await contentPage.close();
await extension.unload();
});

View file

@ -2009,6 +2009,7 @@ STATIC_ATOMS = [
Atom("webRequestFilterResponse_serviceWorkerScript", "webRequestFilterResponse.serviceWorkerScript"),
Atom("http", "http"),
Atom("https", "https"),
Atom("view_source", "view-source"),
Atom("ws", "ws"),
Atom("wss", "wss"),
Atom("ftp", "ftp"),