Bug 1789751 - Remove localhost from MV3 CSP r=mixedpuppy

Differential Revision: https://phabricator.services.mozilla.com/D156758
This commit is contained in:
Rob Wu 2022-09-10 23:49:49 +00:00
parent 9e70d31e32
commit a181c16953
8 changed files with 22 additions and 28 deletions

View file

@ -84,7 +84,7 @@ interface nsIAddonContentPolicy : nsISupports
/* options to pass to validateAddonCSP /* options to pass to validateAddonCSP
* *
* Manifest V2 uses CSP_ALLOW_ANY. * Manifest V2 uses CSP_ALLOW_ANY.
* In Manifest V3, extension_pages would use CSP_ALLOW_LOCALHOST|CSP_ALLOW_WASM * In Manifest V3, extension_pages would use CSP_ALLOW_WASM
* and sandbox would use CSP_ALLOW_EVAL. * and sandbox would use CSP_ALLOW_EVAL.
*/ */
const unsigned long CSP_ALLOW_ANY = 0xFFFF; const unsigned long CSP_ALLOW_ANY = 0xFFFF;

View file

@ -3614,7 +3614,7 @@ pref("extensions.webcompat-reporter.newIssueEndpoint", "https://webcompat.com/is
// Add-on content security policies. // Add-on content security policies.
pref("extensions.webextensions.base-content-security-policy", "script-src 'self' https://* http://localhost:* http://127.0.0.1:* moz-extension: blob: filesystem: 'unsafe-eval' 'wasm-unsafe-eval' 'unsafe-inline';"); pref("extensions.webextensions.base-content-security-policy", "script-src 'self' https://* http://localhost:* http://127.0.0.1:* moz-extension: blob: filesystem: 'unsafe-eval' 'wasm-unsafe-eval' 'unsafe-inline';");
pref("extensions.webextensions.base-content-security-policy.v3", "script-src 'self' 'wasm-unsafe-eval' http://localhost:* http://127.0.0.1:*;"); pref("extensions.webextensions.base-content-security-policy.v3", "script-src 'self' 'wasm-unsafe-eval';");
pref("extensions.webextensions.default-content-security-policy", "script-src 'self' 'wasm-unsafe-eval';"); pref("extensions.webextensions.default-content-security-policy", "script-src 'self' 'wasm-unsafe-eval';");
pref("extensions.webextensions.default-content-security-policy.v3", "script-src 'self';"); pref("extensions.webextensions.default-content-security-policy.v3", "script-src 'self';");

View file

@ -1153,14 +1153,13 @@ const FORMATS = {
}, },
contentSecurityPolicy(string, context) { contentSecurityPolicy(string, context) {
// Manifest V3 extension_pages allows localhost and WASM. When sandbox is // Manifest V3 extension_pages allows WASM. When sandbox is
// implemented, or any other V3 or later directive, the flags // implemented, or any other V3 or later directive, the flags
// logic will need to be updated. // logic will need to be updated.
let flags = let flags =
context.manifestVersion < 3 context.manifestVersion < 3
? Ci.nsIAddonContentPolicy.CSP_ALLOW_ANY ? Ci.nsIAddonContentPolicy.CSP_ALLOW_ANY
: Ci.nsIAddonContentPolicy.CSP_ALLOW_LOCALHOST | : Ci.nsIAddonContentPolicy.CSP_ALLOW_WASM;
Ci.nsIAddonContentPolicy.CSP_ALLOW_WASM;
let error = lazy.contentPolicyService.validateAddonCSP(string, flags); let error = lazy.contentPolicyService.validateAddonCSP(string, flags);
if (error != null) { if (error != null) {
// The CSP validation error is not reported as part of the "choices" error message, // The CSP validation error is not reported as part of the "choices" error message,

View file

@ -49,9 +49,7 @@ static const char kBackgroundPageHTMLEnd[] =
#define BASE_CSP_PREF_V3 \ #define BASE_CSP_PREF_V3 \
"extensions.webextensions.base-content-security-policy.v3" "extensions.webextensions.base-content-security-policy.v3"
#define DEFAULT_BASE_CSP_V3 \ #define DEFAULT_BASE_CSP_V3 "script-src 'self' 'wasm-unsafe-eval';"
"script-src 'self' 'wasm-unsafe-eval' http://localhost:* " \
"http://127.0.0.1:*;"
static const char kRestrictedDomainPref[] = static const char kRestrictedDomainPref[] =
"extensions.webextensions.restrictedDomains"; "extensions.webextensions.restrictedDomains";

View file

@ -203,24 +203,24 @@ add_task(async function test_extension_csp() {
expectedPolicy: aps.defaultCSPV3, expectedPolicy: aps.defaultCSPV3,
}, },
{ {
name: "manifest_v3 allows localhost", name: "manifest_v3 disallows localhost",
manifest: { manifest: {
manifest_version: 3, manifest_version: 3,
content_security_policy: { content_security_policy: {
extension_pages: `script-src 'self' https://localhost`, extension_pages: `script-src 'self' https://localhost`,
}, },
}, },
expectedPolicy: `script-src 'self' https://localhost`, expectedPolicy: aps.defaultCSPV3,
}, },
{ {
name: "manifest_v3 allows 127.0.0.1", name: "manifest_v3 disallows 127.0.0.1",
manifest: { manifest: {
manifest_version: 3, manifest_version: 3,
content_security_policy: { content_security_policy: {
extension_pages: `script-src 'self' https://127.0.0.1`, extension_pages: `script-src 'self' https://127.0.0.1`,
}, },
}, },
expectedPolicy: `script-src 'self' https://127.0.0.1`, expectedPolicy: aps.defaultCSPV3,
}, },
{ {
name: "manifest_v3 allows wasm-unsafe-eval", name: "manifest_v3 allows wasm-unsafe-eval",

View file

@ -202,10 +202,10 @@ add_task(async function test_csp_validator_extension_pages() {
let checkPolicy = (policy, expectedResult, message = null) => { let checkPolicy = (policy, expectedResult, message = null) => {
info(`Checking policy: ${policy}`); info(`Checking policy: ${policy}`);
let result = cps.validateAddonCSP( // While Schemas.jsm uses Ci.nsIAddonContentPolicy.CSP_ALLOW_WASM, we don't
policy, // pass that here because we are only verifying that remote scripts are
Ci.nsIAddonContentPolicy.CSP_ALLOW_LOCALHOST // blocked here.
); let result = cps.validateAddonCSP(policy, 0);
equal(result, expectedResult); equal(result, expectedResult);
}; };
@ -273,14 +273,18 @@ add_task(async function test_csp_validator_extension_pages() {
"\u2018script-src\u2019 directive contains a forbidden 'unsafe-eval' keyword" "\u2018script-src\u2019 directive contains a forbidden 'unsafe-eval' keyword"
); );
// Localhost is always valid // Localhost is invalid
for (let src of [ for (let src of [
"http://localhost", "http://localhost",
"https://localhost", "https://localhost",
"http://127.0.0.1", "http://127.0.0.1",
"https://127.0.0.1", "https://127.0.0.1",
]) { ]) {
checkPolicy(`script-src 'self' ${src};`, null); const protocol = src.split(":")[0];
checkPolicy(
`script-src 'self' ${src};`,
`\u2018script-src\u2019 directive contains a forbidden ${protocol}: protocol source`
);
} }
let directives = ["script-src", "worker-src"]; let directives = ["script-src", "worker-src"];

View file

@ -34,12 +34,7 @@ baseCSP[2] = {
}; };
// Keep in sync with extensions.webextensions.base-content-security-policy.v3 // Keep in sync with extensions.webextensions.base-content-security-policy.v3
baseCSP[3] = { baseCSP[3] = {
"script-src": [ "script-src": ["'self'", "'wasm-unsafe-eval'"],
"http://localhost:*",
"http://127.0.0.1:*",
"'self'",
"'wasm-unsafe-eval'",
],
}; };
/** /**
@ -323,8 +318,8 @@ add_task(async function testCSP() {
await testPolicy({ await testPolicy({
manifest_version: 3, manifest_version: 3,
customCSP: { customCSP: {
"script-src": `'self' http://localhost:123 ${hash}`, "script-src": `'self' ${hash}`,
"worker-src": `'self' http://127.0.0.1:*`, "worker-src": `'self'`,
}, },
expects: { expects: {
workerEvalAllowed: false, workerEvalAllowed: false,

View file

@ -178,8 +178,6 @@ static const char* allowedHostSchemes[] = {"http", "https", "moz-extension",
* worker-src directives may only be the following: * worker-src directives may only be the following:
* - self * - self
* - none * - none
* - Any localhost source, (http://localhost, http://127.0.0.1, or any port
* on those domains)
*/ */
class CSPValidator final : public nsCSPSrcVisitor { class CSPValidator final : public nsCSPSrcVisitor {
public: public: