in src/parsers/manifestjson.js [1170:1247]
validateCspPolicyString(policy, manifestPropName) {
if (typeof policy !== 'string') {
return;
}
const directives = parseCspPolicy(policy);
// The order is important here, 'default-src' needs to be before
// 'script-src' to ensure it can overwrite default-src security policies
const candidates = [
'default-src',
'script-src',
'script-src-elem',
'script-src-attr',
'worker-src',
];
const isSecureCspValue = (value) => CSP_KEYWORD_RE.test(value);
// A missing default-src directive is very permissive, thus insecure:
let insecureSrcDirective = !directives['default-src'];
let warnInsecureCsp = insecureSrcDirective;
let warnInsecureEval = false;
for (let i = 0; i < candidates.length; i++) {
/* eslint-disable no-continue */
const candidate = candidates[i];
if (Object.prototype.hasOwnProperty.call(directives, candidate)) {
const values = directives[candidate];
// If the 'default-src' is insecure, check whether the 'script-src'
// makes it secure, ie 'script-src: self;'
//
// NOTE: this is not yet considering script-src-elem and script-src-attr,
// and it can't be extended to them as is, each of them on their
// own would not fully cover an insecure src directive and they would
// need to be appropriately combined with other directives.
if (
insecureSrcDirective &&
candidate === 'script-src' &&
values.every(isSecureCspValue)
) {
insecureSrcDirective = false;
warnInsecureCsp = false;
continue;
}
for (const value of values) {
// Add a more detailed message for unsafe-eval to avoid confusion
// about why it's forbidden.
if (value === "'unsafe-eval'") {
warnInsecureEval = true;
continue;
}
if (!isSecureCspValue(value)) {
warnInsecureCsp = true;
// everything else looks like something we don't understand
// / support otherwise is invalid so let's warn about that.
if (candidate === 'default-src') {
// Remember insecure 'default-src' to check whether a later
// 'script-src' makes it secure
insecureSrcDirective = true;
}
continue;
}
}
}
}
if (warnInsecureEval) {
this.collector.addWarning(
messages.manifestCspUnsafeEval(manifestPropName)
);
}
if (warnInsecureCsp) {
this.collector.addWarning(messages.manifestCsp(manifestPropName));
}
}