mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-24 21:58:06 +00:00
Bug 855326 - CSP 1.1 nonce-source for scripts and styles r=mrbkap r=dholbert r=geekboy
This commit is contained in:
parent
22a34fc8b5
commit
1da990368c
@ -489,7 +489,8 @@ nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(JSContext *cx)
|
||||
csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_EVAL,
|
||||
fileName,
|
||||
scriptSample,
|
||||
lineNum);
|
||||
lineNum,
|
||||
EmptyString());
|
||||
}
|
||||
|
||||
return evalOK;
|
||||
|
@ -15,7 +15,7 @@ interface nsIDocShell;
|
||||
* one of these per document/principal.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(e5020ec3-1437-46f5-b4eb-8b60766d02c0)]
|
||||
[scriptable, uuid(781b6511-f1fa-4e2c-8eff-1739d091eb2f)]
|
||||
interface nsIContentSecurityPolicy : nsISupports
|
||||
{
|
||||
|
||||
@ -104,6 +104,24 @@ interface nsIContentSecurityPolicy : nsISupports
|
||||
*/
|
||||
boolean getAllowsInlineStyle(out boolean shouldReportViolations);
|
||||
|
||||
/**
|
||||
* Whether this policy accepts the given nonce
|
||||
* @param aNonce
|
||||
* The nonce string to check against the policy
|
||||
* @param aContentType
|
||||
* The type of element on which we encountered this nonce
|
||||
* @param shouldReportViolation
|
||||
* Whether or not the use of an incorrect nonce should be reported.
|
||||
* This function always returns "true" for report-only policies, but when
|
||||
* the report-only policy is violated, shouldReportViolation is true as
|
||||
* well.
|
||||
* @return
|
||||
* Whether or not this nonce is valid
|
||||
*/
|
||||
boolean getAllowsNonce(in AString aNonce,
|
||||
in unsigned long aContentType,
|
||||
out boolean shouldReportViolation);
|
||||
|
||||
/**
|
||||
* For each violated policy (of type violationType), log policy violation on
|
||||
* the Error Console and send a report to report-uris present in the violated
|
||||
@ -117,15 +135,22 @@ interface nsIContentSecurityPolicy : nsISupports
|
||||
* sample of the violating content (to aid debugging)
|
||||
* @param lineNum
|
||||
* source line number of the violation (if available)
|
||||
* @param aNonce
|
||||
* (optional) If this is a nonce violation, include the nonce so we can
|
||||
* recheck to determine which policies were violated and send the
|
||||
* appropriate reports.
|
||||
*/
|
||||
void logViolationDetails(in unsigned short violationType,
|
||||
in AString sourceFile,
|
||||
in AString scriptSample,
|
||||
in int32_t lineNum);
|
||||
in int32_t lineNum,
|
||||
[optional] in AString nonce);
|
||||
|
||||
const unsigned short VIOLATION_TYPE_INLINE_SCRIPT = 1;
|
||||
const unsigned short VIOLATION_TYPE_EVAL = 2;
|
||||
const unsigned short VIOLATION_TYPE_INLINE_STYLE = 3;
|
||||
const unsigned short VIOLATION_TYPE_EVAL = 2;
|
||||
const unsigned short VIOLATION_TYPE_INLINE_STYLE = 3;
|
||||
const unsigned short VIOLATION_TYPE_NONCE_SCRIPT = 4;
|
||||
const unsigned short VIOLATION_TYPE_NONCE_STYLE = 5;
|
||||
|
||||
/**
|
||||
* Called after the CSP object is created to fill in the appropriate request
|
||||
|
@ -24,7 +24,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
|
||||
// Module stuff
|
||||
this.EXPORTED_SYMBOLS = ["CSPRep", "CSPSourceList", "CSPSource", "CSPHost",
|
||||
"CSPdebug", "CSPViolationReportListener", "CSPLocalizer"];
|
||||
"CSPdebug", "CSPViolationReportListener", "CSPLocalizer",
|
||||
"CSPPrefObserver"];
|
||||
|
||||
var STRINGS_URI = "chrome://global/locale/security/csp.properties";
|
||||
|
||||
@ -65,25 +66,37 @@ const R_EXTHOSTSRC = new RegExp ("^" + R_HOSTSRC.source + "\\/[:print:]+$", 'i')
|
||||
// keyword-source = "'self'" / "'unsafe-inline'" / "'unsafe-eval'"
|
||||
const R_KEYWORDSRC = new RegExp ("^('self'|'unsafe-inline'|'unsafe-eval')$", 'i');
|
||||
|
||||
// nonce-source = "'nonce-" nonce-value "'"
|
||||
// nonce-value = 1*( ALPHA / DIGIT / "+" / "/" )
|
||||
const R_NONCESRC = new RegExp ("^'nonce-([a-zA-Z0-9\+\/]+)'$", 'i');
|
||||
|
||||
// source-exp = scheme-source / host-source / keyword-source
|
||||
const R_SOURCEEXP = new RegExp (R_SCHEMESRC.source + "|" +
|
||||
R_HOSTSRC.source + "|" +
|
||||
R_KEYWORDSRC.source, 'i');
|
||||
R_KEYWORDSRC.source + "|" +
|
||||
R_NONCESRC.source, 'i');
|
||||
|
||||
|
||||
var gPrefObserver = {
|
||||
this.CSPPrefObserver = {
|
||||
get debugEnabled () {
|
||||
if (!this._branch)
|
||||
this._initialize();
|
||||
return this._debugEnabled;
|
||||
},
|
||||
|
||||
get experimentalEnabled () {
|
||||
if (!this._branch)
|
||||
this._initialize();
|
||||
return this._experimentalEnabled;
|
||||
},
|
||||
|
||||
_initialize: function() {
|
||||
var prefSvc = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Ci.nsIPrefService);
|
||||
this._branch = prefSvc.getBranch("security.csp.");
|
||||
this._branch.addObserver("", this, false);
|
||||
this._debugEnabled = this._branch.getBoolPref("debug");
|
||||
this._experimentalEnabled = this._branch.getBoolPref("experimentalEnabled");
|
||||
},
|
||||
|
||||
unregister: function() {
|
||||
@ -95,11 +108,13 @@ var gPrefObserver = {
|
||||
if (aTopic != "nsPref:changed") return;
|
||||
if (aData === "debug")
|
||||
this._debugEnabled = this._branch.getBoolPref("debug");
|
||||
if (aData === "experimentalEnabled")
|
||||
this._experimentalEnabled = this._branch.getBoolPref("experimentalEnabled");
|
||||
},
|
||||
};
|
||||
|
||||
this.CSPdebug = function CSPdebug(aMsg) {
|
||||
if (!gPrefObserver.debugEnabled) return;
|
||||
if (!CSPPrefObserver.debugEnabled) return;
|
||||
|
||||
aMsg = 'CSP debug: ' + aMsg + "\n";
|
||||
Components.classes["@mozilla.org/consoleservice;1"]
|
||||
@ -793,14 +808,28 @@ CSPRep.prototype = {
|
||||
|
||||
/**
|
||||
* Determines if this policy accepts a URI.
|
||||
* @param aContext
|
||||
* @param aURI
|
||||
* URI of the requested resource
|
||||
* @param aDirective
|
||||
* one of the SRC_DIRECTIVES defined above
|
||||
* @param aContext
|
||||
* Context of the resource being requested. This is a type inheriting
|
||||
* from nsIDOMHTMLElement if this is called from shouldLoad to check
|
||||
* an external resource load, and refers to the HTML element that is
|
||||
* causing the resource load. Otherwise, it is a string containing
|
||||
* a nonce from a nonce="" attribute if it is called from
|
||||
* getAllowsNonce.
|
||||
* @returns
|
||||
* true if the policy permits the URI in given context.
|
||||
*/
|
||||
permits:
|
||||
function csp_permits(aURI, aContext) {
|
||||
if (!aURI) return false;
|
||||
function csp_permits(aURI, aDirective, aContext) {
|
||||
// In the case where permits is called from getAllowsNonce (for an inline
|
||||
// element), aURI is null and aContext has a specific value. Otherwise,
|
||||
// calling permits without aURI is invalid.
|
||||
let checking_nonce = aContext instanceof Ci.nsIDOMHTMLElement ||
|
||||
typeof aContext === 'string';
|
||||
if (!aURI && !checking_nonce) return false;
|
||||
|
||||
// GLOBALLY ALLOW "about:" SCHEME
|
||||
if (aURI instanceof String && aURI.substring(0,6) === "about:")
|
||||
@ -811,13 +840,13 @@ CSPRep.prototype = {
|
||||
// make sure the right directive set is used
|
||||
let DIRS = this._specCompliant ? CSPRep.SRC_DIRECTIVES_NEW : CSPRep.SRC_DIRECTIVES_OLD;
|
||||
|
||||
let contextIsSrcDir = false;
|
||||
let directiveInPolicy = false;
|
||||
for (var i in DIRS) {
|
||||
if (DIRS[i] === aContext) {
|
||||
if (DIRS[i] === aDirective) {
|
||||
// for catching calls with invalid contexts (below)
|
||||
contextIsSrcDir = true;
|
||||
if (this._directives.hasOwnProperty(aContext)) {
|
||||
return this._directives[aContext].permits(aURI);
|
||||
directiveInPolicy = true;
|
||||
if (this._directives.hasOwnProperty(aDirective)) {
|
||||
return this._directives[aDirective].permits(aURI, aContext);
|
||||
}
|
||||
//found matching dir, can stop looking
|
||||
break;
|
||||
@ -825,15 +854,15 @@ CSPRep.prototype = {
|
||||
}
|
||||
|
||||
// frame-ancestors is a special case; it doesn't fall back to default-src.
|
||||
if (aContext === DIRS.FRAME_ANCESTORS)
|
||||
if (aDirective === DIRS.FRAME_ANCESTORS)
|
||||
return true;
|
||||
|
||||
// All directives that don't fall back to default-src should have an escape
|
||||
// hatch above (like frame-ancestors).
|
||||
if (!contextIsSrcDir) {
|
||||
if (!directiveInPolicy) {
|
||||
// if this code runs, there's probably something calling permits() that
|
||||
// shouldn't be calling permits().
|
||||
CSPdebug("permits called with invalid load type: " + aContext);
|
||||
CSPdebug("permits called with invalid load type: " + aDirective);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -842,7 +871,7 @@ CSPRep.prototype = {
|
||||
// indicates no relevant directives were present and the load should be
|
||||
// permitted).
|
||||
if (this._directives.hasOwnProperty(DIRS.DEFAULT_SRC)) {
|
||||
return this._directives[DIRS.DEFAULT_SRC].permits(aURI);
|
||||
return this._directives[DIRS.DEFAULT_SRC].permits(aURI, aContext);
|
||||
}
|
||||
|
||||
// no relevant directives present -- this means for CSP 1.0 that the load
|
||||
@ -1081,12 +1110,12 @@ CSPSourceList.prototype = {
|
||||
* true if the URI matches a source in this source list.
|
||||
*/
|
||||
permits:
|
||||
function cspsd_permits(aURI) {
|
||||
function cspsd_permits(aURI, aContext) {
|
||||
if (this.isNone()) return false;
|
||||
if (this.isAll()) return true;
|
||||
|
||||
for (var i in this._sources) {
|
||||
if (this._sources[i].permits(aURI)) {
|
||||
if (this._sources[i].permits(aURI, aContext)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1102,6 +1131,7 @@ this.CSPSource = function CSPSource() {
|
||||
this._scheme = undefined;
|
||||
this._port = undefined;
|
||||
this._host = undefined;
|
||||
this._nonce = undefined;
|
||||
|
||||
//when set to true, this allows all source
|
||||
this._permitAll = false;
|
||||
@ -1346,6 +1376,19 @@ CSPSource.fromString = function(aStr, aCSPRep, self, enforceSelfChecks) {
|
||||
return sObj;
|
||||
}
|
||||
|
||||
// check for a nonce-source match
|
||||
if (R_NONCESRC.test(aStr)) {
|
||||
// We can't put this check outside of the regex test because R_NONCESRC is
|
||||
// included in R_SOURCEEXP, which is const. By testing here, we can
|
||||
// explicitly return null for nonces if experimental is not enabled,
|
||||
// instead of letting it fall through and assuming it won't accidentally
|
||||
// match something later in this function.
|
||||
if (!CSPPrefObserver.experimentalEnabled) return null;
|
||||
var nonceSrcMatch = R_NONCESRC.exec(aStr);
|
||||
sObj._nonce = nonceSrcMatch[1];
|
||||
return sObj;
|
||||
}
|
||||
|
||||
// check for 'self' (case insensitive)
|
||||
if (aStr.toUpperCase() === "'SELF'") {
|
||||
if (!self) {
|
||||
@ -1450,6 +1493,8 @@ CSPSource.prototype = {
|
||||
s = s + this._host;
|
||||
if (this.port)
|
||||
s = s + ":" + this.port;
|
||||
if (this._nonce)
|
||||
s = s + "'nonce-" + this._nonce + "'";
|
||||
return s;
|
||||
},
|
||||
|
||||
@ -1465,6 +1510,7 @@ CSPSource.prototype = {
|
||||
aClone._scheme = this._scheme;
|
||||
aClone._port = this._port;
|
||||
aClone._host = this._host ? this._host.clone() : undefined;
|
||||
aClone._nonce = this._nonce;
|
||||
aClone._isSelf = this._isSelf;
|
||||
aClone._CSPRep = this._CSPRep;
|
||||
return aClone;
|
||||
@ -1474,11 +1520,24 @@ CSPSource.prototype = {
|
||||
* Determines if this Source accepts a URI.
|
||||
* @param aSource
|
||||
* the URI, or CSPSource in question
|
||||
* @param aContext
|
||||
* the context of the resource being loaded
|
||||
* @returns
|
||||
* true if the URI matches a source in this source list.
|
||||
*/
|
||||
permits:
|
||||
function(aSource) {
|
||||
function(aSource, aContext) {
|
||||
if (this._nonce && CSPPrefObserver.experimentalEnabled) {
|
||||
if (aContext instanceof Ci.nsIDOMHTMLElement) {
|
||||
return this._nonce === aContext.getAttribute('nonce');
|
||||
} else if (typeof aContext === 'string') {
|
||||
return this._nonce === aContext;
|
||||
}
|
||||
}
|
||||
// We only use aContext for nonce checks. If it's otherwise provided,
|
||||
// ignore it.
|
||||
if (!CSPPrefObserver.experimentalEnabled && aContext) return false;
|
||||
|
||||
if (!aSource) return false;
|
||||
|
||||
if (!(aSource instanceof CSPSource))
|
||||
|
@ -31,6 +31,8 @@ const ERROR_FLAG = Ci.nsIScriptError.ERROR_FLAG;
|
||||
const INLINE_STYLE_VIOLATION_OBSERVER_SUBJECT = 'violated base restriction: Inline Stylesheets will not apply';
|
||||
const INLINE_SCRIPT_VIOLATION_OBSERVER_SUBJECT = 'violated base restriction: Inline Scripts will not execute';
|
||||
const EVAL_VIOLATION_OBSERVER_SUBJECT = 'violated base restriction: Code will not be created from strings';
|
||||
const SCRIPT_NONCE_VIOLATION_OBSERVER_SUBJECT = 'Inline Script had invalid nonce'
|
||||
const STYLE_NONCE_VIOLATION_OBSERVER_SUBJECT = 'Inline Style had invalid nonce'
|
||||
|
||||
// The cutoff length of content location in creating CSP cache key.
|
||||
const CSP_CACHE_URI_CUTOFF_SIZE = 512;
|
||||
@ -189,6 +191,28 @@ ContentSecurityPolicy.prototype = {
|
||||
});
|
||||
},
|
||||
|
||||
getAllowsNonce: function(aNonce, aContentType, shouldReportViolation) {
|
||||
if (!CSPPrefObserver.experimentalEnabled)
|
||||
return false;
|
||||
|
||||
if (!(aContentType == Ci.nsIContentPolicy.TYPE_SCRIPT ||
|
||||
aContentType == Ci.nsIContentPolicy.TYPE_STYLESHEET)) {
|
||||
CSPdebug("Nonce check requested for an invalid content type (not script or style): " + aContentType);
|
||||
return false;
|
||||
}
|
||||
let ct = ContentSecurityPolicy._MAPPINGS[aContentType];
|
||||
|
||||
// allow it to execute?
|
||||
let policyAllowsNonce = [ policy.permits(null, ct, aNonce) for (policy of this._policies) ];
|
||||
|
||||
shouldReportViolation.value = policyAllowsNonce.some(function(a) { return !a; });
|
||||
|
||||
// allow it to execute? (Do all the policies allow it to execute)?
|
||||
return this._policies.every(function(policy, i) {
|
||||
return policy._reportOnlyMode || policyAllowsNonce[i];
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* For each policy, log any violation on the Error Console and send a report
|
||||
* if a report-uri is present in the policy
|
||||
@ -201,9 +225,13 @@ ContentSecurityPolicy.prototype = {
|
||||
* sample of the violating content (to aid debugging)
|
||||
* @param aLineNum
|
||||
* source line number of the violation (if available)
|
||||
* @param aNonce
|
||||
* (optional) If this is a nonce violation, include the nonce should we
|
||||
* can recheck to determine which policies were violated and send the
|
||||
* appropriate reports.
|
||||
*/
|
||||
logViolationDetails:
|
||||
function(aViolationType, aSourceFile, aScriptSample, aLineNum, violatedPolicyIndex) {
|
||||
function(aViolationType, aSourceFile, aScriptSample, aLineNum, aNonce) {
|
||||
for (let policyIndex=0; policyIndex < this._policies.length; policyIndex++) {
|
||||
let policy = this._policies[policyIndex];
|
||||
|
||||
@ -237,6 +265,24 @@ ContentSecurityPolicy.prototype = {
|
||||
aSourceFile, aScriptSample, aLineNum);
|
||||
}
|
||||
break;
|
||||
case Ci.nsIContentSecurityPolicy.VIOLATION_TYPE_NONCE_SCRIPT:
|
||||
let scriptType = ContentSecurityPolicy._MAPPINGS[Ci.nsIContentPolicy.TYPE_SCRIPT];
|
||||
if (!policy.permits(null, scriptType, aNonce)) {
|
||||
var violatedDirective = this._buildViolatedDirectiveString('SCRIPT_SRC', policy);
|
||||
this._asyncReportViolation('self', null, violatedDirective, policyIndex,
|
||||
SCRIPT_NONCE_VIOLATION_OBSERVER_SUBJECT,
|
||||
aSourceFile, aScriptSample, aLineNum);
|
||||
}
|
||||
break;
|
||||
case Ci.nsIContentSecurityPolicy.VIOLATION_TYPE_NONCE_STYLE:
|
||||
let styleType = ContentSecurityPolicy._MAPPINGS[Ci.nsIContentPolicy.TYPE_STYLE];
|
||||
if (!policy.permits(null, styleType, aNonce)) {
|
||||
var violatedDirective = this._buildViolatedDirectiveString('STYLE_SRC', policy);
|
||||
this._asyncReportViolation('self', null, violatedDirective, policyIndex,
|
||||
STYLE_NONCE_VIOLATION_OBSERVER_SUBJECT,
|
||||
aSourceFile, aScriptSample, aLineNum);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -628,6 +674,14 @@ ContentSecurityPolicy.prototype = {
|
||||
|
||||
let cp = Ci.nsIContentPolicy;
|
||||
|
||||
// Infer if this is a preload for elements that use nonce-source. Since,
|
||||
// for preloads, aContext is the document and not the element associated
|
||||
// with the resource, we cannot determine the nonce. See Bug 612921 and
|
||||
// Bug 855326.
|
||||
var possiblePreloadNonceConflict =
|
||||
(aContentType == cp.TYPE_SCRIPT || aContentType == cp.TYPE_STYLESHEET) &&
|
||||
aContext instanceof Ci.nsIDOMHTMLDocument;
|
||||
|
||||
// iterate through all the _policies and send reports where a policy is
|
||||
// violated. After the check, determine the overall effect (blocked or
|
||||
// loaded?) and cache it.
|
||||
@ -661,15 +715,18 @@ ContentSecurityPolicy.prototype = {
|
||||
|
||||
// otherwise, honor the translation
|
||||
// var source = aContentLocation.scheme + "://" + aContentLocation.hostPort;
|
||||
var res = policy.permits(aContentLocation, cspContext)
|
||||
? cp.ACCEPT : cp.REJECT_SERVER;
|
||||
let context = CSPPrefObserver.experimentalEnabled ? aContext : null;
|
||||
var res = policy.permits(aContentLocation, cspContext, context) ?
|
||||
cp.ACCEPT : cp.REJECT_SERVER;
|
||||
// record whether the thing should be blocked or just reported.
|
||||
policyAllowsLoadArray.push(res == cp.ACCEPT || policy._reportOnlyMode);
|
||||
|
||||
// frame-ancestors is taken care of early on (as this document is loaded)
|
||||
|
||||
// If the result is *NOT* ACCEPT, then send report
|
||||
if (res != Ci.nsIContentPolicy.ACCEPT) {
|
||||
// Do not send report if this is a nonce-source preload - the decision may
|
||||
// be wrong and will incorrectly fail the unit tests.
|
||||
if (res != Ci.nsIContentPolicy.ACCEPT && !possiblePreloadNonceConflict) {
|
||||
CSPdebug("blocking request for " + aContentLocation.asciiSpec);
|
||||
try {
|
||||
let directive = "unknown directive",
|
||||
@ -704,7 +761,8 @@ ContentSecurityPolicy.prototype = {
|
||||
let ret = (policyAllowsLoadArray.some(function(a,b) { return !a; }) ?
|
||||
cp.REJECT_SERVER : cp.ACCEPT);
|
||||
|
||||
if (key) {
|
||||
// Do not cache the result if this is a nonce-source preload
|
||||
if (key && !possiblePreloadNonceConflict) {
|
||||
this._cache[key] = ret;
|
||||
}
|
||||
return ret;
|
||||
|
@ -608,6 +608,7 @@ GK_ATOM(nodeSet, "node-set")
|
||||
GK_ATOM(noembed, "noembed")
|
||||
GK_ATOM(noframes, "noframes")
|
||||
GK_ATOM(nohref, "nohref")
|
||||
GK_ATOM(nonce, "nonce")
|
||||
GK_ATOM(none, "none")
|
||||
GK_ATOM(noresize, "noresize")
|
||||
GK_ATOM(normal, "normal")
|
||||
|
@ -624,13 +624,31 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
if (csp) {
|
||||
PR_LOG(gCspPRLog, PR_LOG_DEBUG, ("New ScriptLoader i ****with CSP****"));
|
||||
bool inlineOK = true;
|
||||
bool reportViolations = false;
|
||||
rv = csp->GetAllowsInlineScript(&reportViolations, &inlineOK);
|
||||
PR_LOG(gCspPRLog, PR_LOG_DEBUG, ("New ScriptLoader ****with CSP****"));
|
||||
|
||||
bool reportViolation = false;
|
||||
bool allowInlineScript = true;
|
||||
rv = csp->GetAllowsInlineScript(&reportViolation, &allowInlineScript);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
if (reportViolations) {
|
||||
bool foundNonce = false;
|
||||
nsAutoString nonce;
|
||||
if (!allowInlineScript) {
|
||||
foundNonce = scriptContent->GetAttr(kNameSpaceID_None, nsGkAtoms::nonce, nonce);
|
||||
if (foundNonce) {
|
||||
// We can overwrite the outparams from GetAllowsInlineScript because
|
||||
// if the nonce is correct, then we don't want to report the original
|
||||
// inline violation (it has been whitelisted by the nonce), and if
|
||||
// the nonce is incorrect, then we want to return just the specific
|
||||
// "nonce violation" rather than both a "nonce violation" and
|
||||
// a generic "inline violation".
|
||||
rv = csp->GetAllowsNonce(nonce, nsIContentPolicy::TYPE_SCRIPT,
|
||||
&reportViolation, &allowInlineScript);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (reportViolation) {
|
||||
// gather information to log with violation report
|
||||
nsIURI* uri = mDocument->GetDocumentURI();
|
||||
nsAutoCString asciiSpec;
|
||||
@ -641,17 +659,21 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
||||
// cap the length of the script sample at 40 chars
|
||||
if (scriptText.Length() > 40) {
|
||||
scriptText.Truncate(40);
|
||||
scriptText.Append(NS_LITERAL_STRING("..."));
|
||||
scriptText.AppendLiteral("...");
|
||||
}
|
||||
|
||||
csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_INLINE_SCRIPT,
|
||||
NS_ConvertUTF8toUTF16(asciiSpec),
|
||||
scriptText,
|
||||
aElement->GetScriptLineNumber());
|
||||
// The type of violation to report is determined by whether there was
|
||||
// a nonce present.
|
||||
unsigned short violationType = foundNonce ?
|
||||
nsIContentSecurityPolicy::VIOLATION_TYPE_NONCE_SCRIPT :
|
||||
nsIContentSecurityPolicy::VIOLATION_TYPE_INLINE_SCRIPT;
|
||||
csp->LogViolationDetails(violationType, NS_ConvertUTF8toUTF16(asciiSpec),
|
||||
scriptText, aElement->GetScriptLineNumber(), nonce);
|
||||
}
|
||||
|
||||
if (!inlineOK) {
|
||||
PR_LOG(gCspPRLog, PR_LOG_DEBUG, ("CSP blocked inline scripts (2)"));
|
||||
if (!allowInlineScript) {
|
||||
NS_ASSERTION(reportViolation,
|
||||
"CSP blocked inline script but is not reporting a violation");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -360,7 +360,10 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument *aOldDocument,
|
||||
nsAutoString text;
|
||||
nsContentUtils::GetNodeTextContent(thisContent, false, text);
|
||||
|
||||
if (!nsStyleUtil::CSPAllowsInlineStyle(thisContent->NodePrincipal(),
|
||||
MOZ_ASSERT(thisContent->Tag() != nsGkAtoms::link,
|
||||
"<link> is not 'inline', and needs different CSP checks");
|
||||
if (!nsStyleUtil::CSPAllowsInlineStyle(thisContent,
|
||||
thisContent->NodePrincipal(),
|
||||
doc->GetDocumentURI(),
|
||||
mLineNumber, text, &rv))
|
||||
return rv;
|
||||
|
@ -236,7 +236,7 @@ nsStyledElementNotElementCSSInlineStyle::ParseStyleAttribute(const nsAString& aV
|
||||
{
|
||||
nsIDocument* doc = OwnerDoc();
|
||||
|
||||
if (!nsStyleUtil::CSPAllowsInlineStyle(NodePrincipal(),
|
||||
if (!nsStyleUtil::CSPAllowsInlineStyle(nullptr, NodePrincipal(),
|
||||
doc->GetDocumentURI(), 0, aValue,
|
||||
nullptr))
|
||||
return;
|
||||
|
67
content/base/test/csp/file_nonce_source.html
Normal file
67
content/base/test/csp/file_nonce_source.html
Normal file
@ -0,0 +1,67 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<!-- external styles -->
|
||||
<link rel='stylesheet' nonce="correctstylenonce" href="file_CSP.sjs?testid=external_style_correct_nonce_good&type=text/css" />
|
||||
<link rel='stylesheet' nonce="incorrectstylenonce" href="file_CSP.sjs?testid=external_style_incorrect_nonce_bad&type=text/css" />
|
||||
<link rel='stylesheet' nonce="correctscriptnonce" href="file_CSP.sjs?testid=external_style_correct_script_nonce_bad&type=text/css" />
|
||||
<link rel='stylesheet' href="file_CSP.sjs?testid=external_style_no_nonce_bad&type=text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<!-- inline scripts -->
|
||||
<script nonce="correctscriptnonce">
|
||||
window.parent.inlineScriptTestResult("allowed", "allowed", "This script has a correct nonce for scripts");
|
||||
</script>
|
||||
<script nonce="incorrectscriptnonce">
|
||||
window.parent.inlineScriptTestResult("allowed", "blocked", "This script has an incorrect nonce for scripts");
|
||||
</script>
|
||||
<script nonce="correctstylenonce">
|
||||
window.parent.inlineScriptTestResult("allowed", "blocked", "This script has a correct nonce for styles (but not for scripts)");
|
||||
</script>
|
||||
<script>
|
||||
window.parent.inlineScriptTestResult("allowed", "blocked", "This script has no nonce");
|
||||
</script>
|
||||
|
||||
<!-- external scripts -->
|
||||
<script nonce="correctscriptnonce" src="http://example.org/tests/content/base/test/csp/file_CSP.sjs?testid=external_script_correct_nonce_good&type=text/javascript"></script>
|
||||
<script nonce="anothercorrectscriptnonce" src="http://example.org/tests/content/base/test/csp/file_CSP.sjs?testid=external_script_another_correct_nonce_good&type=text/javascript"></script>
|
||||
<script nonce="incorrectscriptnonce" src="http://example.org/tests/content/base/test/csp/file_CSP.sjs?testid=external_script_incorrect_nonce_bad&type=text/javascript"></script>
|
||||
<script nonce="correctstylenonce" src="http://example.org/tests/content/base/test/csp/file_CSP.sjs?testid=external_script_correct_style_nonce_bad&type=text/javascript"></script>
|
||||
<script src="http://example.org/tests/content/base/test/csp/file_CSP.sjs?testid=external_script_no_nonce_bad&type=text/javascript"></script>
|
||||
|
||||
<!-- This external script has the correct nonce and comes from a whitelisted URI. It should be allowed. -->
|
||||
<script nonce="correctscriptnonce" src="file_CSP.sjs?testid=external_script_correct_nonce_correct_uri_good&type=text/javascript"></script>
|
||||
<!-- This external script has an incorrect nonce, but comes from a whitelisted URI. It should be allowed. -->
|
||||
<script nonce="incorrectscriptnonce" src="file_CSP.sjs?testid=external_script_incorrect_nonce_correct_uri_good&type=text/javascript"></script>
|
||||
<!-- This external script has no nonce and comes from a whitelisted URI. It should be allowed. -->
|
||||
<script src="file_CSP.sjs?testid=external_script_no_nonce_correct_uri_good&type=text/javascript"></script>
|
||||
|
||||
<!-- inline styles -->
|
||||
<ol>
|
||||
<li id=inline-style-correct-nonce>
|
||||
(inline style with correct nonce) This text should be green
|
||||
</li>
|
||||
<li id=inline-style-incorrect-nonce>
|
||||
(inline style with incorrect nonce) This text should be black
|
||||
</li>
|
||||
<li id=inline-style-correct-script-nonce>
|
||||
(inline style with correct script, not style, nonce) This text should be black
|
||||
</li>
|
||||
<li id=inline-style-no-nonce>
|
||||
(inline style with no nonce) This text should be black
|
||||
</li>
|
||||
</ol>
|
||||
<style nonce=correctstylenonce>
|
||||
li#inline-style-correct-nonce { color: green; }
|
||||
</style>
|
||||
<style nonce=incorrectstylenonce>
|
||||
li#inline-style-incorrect-nonce { color: red; }
|
||||
</style>
|
||||
<style nonce=correctscriptnonce>
|
||||
li#inline-style-correct-script-nonce { color: red; }
|
||||
</style>
|
||||
<style>
|
||||
li#inline-style-no-nonce { color: red; }
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
2
content/base/test/csp/file_nonce_source.html^headers^
Normal file
2
content/base/test/csp/file_nonce_source.html^headers^
Normal file
@ -0,0 +1,2 @@
|
||||
Content-Security-Policy: script-src 'self' 'nonce-correctscriptnonce' 'nonce-anothercorrectscriptnonce'; style-src 'nonce-correctstylenonce';
|
||||
Cache-Control: no-cache
|
@ -85,6 +85,8 @@ support-files =
|
||||
file_policyuri_regression_from_multipolicy.html
|
||||
file_policyuri_regression_from_multipolicy.html^headers^
|
||||
file_policyuri_regression_from_multipolicy_policy
|
||||
file_nonce_source.html
|
||||
file_nonce_source.html^headers^
|
||||
|
||||
[test_CSP.html]
|
||||
[test_CSP_bug663567.html]
|
||||
@ -103,3 +105,4 @@ support-files =
|
||||
[test_CSP_bug910139.html]
|
||||
[test_CSP_bug909029.html]
|
||||
[test_policyuri_regression_from_multipolicy.html]
|
||||
[test_nonce_source.html]
|
||||
|
149
content/base/test/csp/test_nonce_source.html
Normal file
149
content/base/test/csp/test_nonce_source.html
Normal file
@ -0,0 +1,149 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test CSP 1.1 nonce-source for scripts and styles</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="visibility:hidden">
|
||||
<iframe style="width:100%;" id='cspframe'></iframe>
|
||||
</div>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
var testsRun = 0;
|
||||
var totalTests = 20;
|
||||
|
||||
var inlineScriptTestsRun = 0;
|
||||
var totalInlineScriptTests = 4;
|
||||
|
||||
var scriptNonceViolations = 0;
|
||||
var expectedScriptNonceViolations = 2;
|
||||
var scriptInlineViolations = 0;
|
||||
var expectedScriptInlineViolations = 1;
|
||||
|
||||
// This is used to watch the blocked data bounce off CSP
|
||||
function examiner() {
|
||||
SpecialPowers.addObserver(this, "http-on-modify-request", false);
|
||||
SpecialPowers.addObserver(this, "csp-on-violate-policy", false);
|
||||
}
|
||||
|
||||
examiner.prototype = {
|
||||
observe: function(subject, topic, data) {
|
||||
if (!SpecialPowers.can_QI(subject))
|
||||
return;
|
||||
|
||||
var testid_re = new RegExp("testid=([a-z0-9_]+)");
|
||||
|
||||
//_good things better be allowed!
|
||||
//_bad things better be blocked!
|
||||
|
||||
if (topic === "http-on-modify-request") {
|
||||
// these things were allowed by CSP
|
||||
var allowed_uri = SpecialPowers.getPrivilegedProps(SpecialPowers.do_QueryInterface(subject, "nsIHttpChannel"), "URI.asciiSpec");
|
||||
if (!testid_re.test(allowed_uri)) return;
|
||||
var testid = testid_re.exec(allowed_uri)[1];
|
||||
ok(/_good/.test(testid), "Allowed URI with testid " + testid);
|
||||
ranTests(1);
|
||||
}
|
||||
|
||||
if (topic === "csp-on-violate-policy") {
|
||||
try {
|
||||
// if it is an blocked external load, subject will be the URI of the resource
|
||||
var blocked_uri = SpecialPowers.getPrivilegedProps(SpecialPowers.do_QueryInterface(subject, "nsIURI"), "asciiSpec");
|
||||
if (!testid_re.test(blocked_uri)) return;
|
||||
var testid = testid_re.exec(blocked_uri)[1];
|
||||
ok(/_bad/.test(testid), "Blocked URI with testid " + testid);
|
||||
ranTests(1);
|
||||
} catch (e) {
|
||||
// if the subject is blocked inline, data will be a violation msg (defined at the top of contentSecurityPolicy.js)
|
||||
var violation_msg = SpecialPowers.getPrivilegedProps(SpecialPowers.do_QueryInterface(subject, "nsISupportsCString"), "data");
|
||||
if (/Inline Script/.test(violation_msg)) {
|
||||
if (/Inline Script had invalid nonce/.test(violation_msg))
|
||||
scriptNonceViolations++;
|
||||
if (/Inline Scripts will not execute/.test(violation_msg))
|
||||
scriptInlineViolations++;
|
||||
window.inlineScriptTestResult("blocked", "blocked",
|
||||
"Blocked because " + violation_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// must eventually call this to remove the listener, or mochitests might get borked.
|
||||
remove: function() {
|
||||
SpecialPowers.removeObserver(this, "http-on-modify-request");
|
||||
SpecialPowers.removeObserver(this, "csp-on-violate-policy");
|
||||
}
|
||||
}
|
||||
|
||||
var inlineScriptTestResult = function(testIs, testShouldBe, description) {
|
||||
if (testIs !== testShouldBe) {
|
||||
ok(false, description);
|
||||
} else {
|
||||
ok(true, description);
|
||||
}
|
||||
ranTests(1)
|
||||
|
||||
inlineScriptTestsRun++;
|
||||
if (inlineScriptTestsRun == totalInlineScriptTests) {
|
||||
if (scriptNonceViolations != expectedScriptNonceViolations)
|
||||
ok(false, "The number of reported script nonce violations does not match expected; got " + scriptNonceViolations + ", expected " + expectedScriptNonceViolations);
|
||||
if (scriptInlineViolations != expectedScriptInlineViolations)
|
||||
ok(false, "The number of reported inline script violations does not match expected; got " + scriptInlineViolations + ", expected " + expectedScriptInlineViolations);
|
||||
ranTests(2);
|
||||
}
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
// remove the observer so we don't bork other tests
|
||||
window.examiner.remove();
|
||||
// finish the tests
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function ranTests(num) {
|
||||
testsRun += num;
|
||||
if (testsRun < totalTests) {
|
||||
return;
|
||||
}
|
||||
cleanup();
|
||||
}
|
||||
|
||||
function checkStyles () {
|
||||
var cspframe = document.getElementById('cspframe');
|
||||
var getElementColorById = function (id) {
|
||||
return window.getComputedStyle(cspframe.contentDocument.getElementById(id), null).color;
|
||||
};
|
||||
// Inline style tries to change an element's color to green. If blocked, the
|
||||
// element's color will be the default black.
|
||||
var green = "rgb(0, 128, 0)";
|
||||
var black = "rgb(0, 0, 0)";
|
||||
|
||||
is(getElementColorById('inline-style-correct-nonce'), green, "Inline style with correct nonce allowed");
|
||||
is(getElementColorById('inline-style-incorrect-nonce'), black, "Inline style with incorrect nonce blocked");
|
||||
is(getElementColorById('inline-style-correct-script-nonce'), black, "Inline style with correct nonce for scripts (but incorrect nonce for styles) blocked");
|
||||
is(getElementColorById('inline-style-no-nonce'), black, "Inline style with no nonce blocked");
|
||||
|
||||
ranTests(4);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// set up and go
|
||||
window.examiner = new examiner();
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set':[["security.csp.speccompliant", true],
|
||||
["security.csp.experimentalEnabled", true]]},
|
||||
function() {
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe').src = 'file_nonce_source.html';
|
||||
document.getElementById('cspframe').addEventListener('load', checkStyles, false);
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -729,7 +729,8 @@ nsEventListenerManager::SetEventHandler(nsIAtom *aName,
|
||||
csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_INLINE_SCRIPT,
|
||||
NS_ConvertUTF8toUTF16(asciiSpec),
|
||||
scriptSample,
|
||||
0);
|
||||
0,
|
||||
EmptyString());
|
||||
}
|
||||
|
||||
// return early if CSP wants us to block inline scripts
|
||||
|
@ -394,7 +394,8 @@ nsSMILCSSValueType::ValueFromString(nsCSSProperty aPropID,
|
||||
}
|
||||
|
||||
nsIDocument* doc = aTargetElement->GetCurrentDoc();
|
||||
if (doc && !nsStyleUtil::CSPAllowsInlineStyle(doc->NodePrincipal(),
|
||||
if (doc && !nsStyleUtil::CSPAllowsInlineStyle(nullptr,
|
||||
doc->NodePrincipal(),
|
||||
doc->GetDocumentURI(),
|
||||
0, aString, nullptr)) {
|
||||
return;
|
||||
|
@ -181,7 +181,7 @@ CheckCSPForEval(JSContext* aCx, nsGlobalWindow* aWindow, ErrorResult& aError)
|
||||
}
|
||||
|
||||
csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_EVAL,
|
||||
fileNameString, scriptSample, lineNum);
|
||||
fileNameString, scriptSample, lineNum, EmptyString());
|
||||
}
|
||||
|
||||
return allowsEval;
|
||||
|
@ -179,7 +179,8 @@ nsresult nsJSThunk::EvaluateScript(nsIChannel *aChannel,
|
||||
csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_INLINE_SCRIPT,
|
||||
NS_ConvertUTF8toUTF16(asciiSpec),
|
||||
NS_ConvertUTF8toUTF16(mURL),
|
||||
0);
|
||||
0,
|
||||
EmptyString());
|
||||
}
|
||||
|
||||
//return early if inline scripts are not allowed
|
||||
|
@ -707,7 +707,7 @@ public:
|
||||
"Call to eval() or related function blocked by CSP.");
|
||||
if (mWorkerPrivate->GetReportCSPViolations()) {
|
||||
csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_EVAL,
|
||||
mFileName, scriptSample, mLineNum);
|
||||
mFileName, scriptSample, mLineNum, EmptyString());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "nsCSSProps.h"
|
||||
#include "nsRuleNode.h"
|
||||
#include "nsROCSSPrimitiveValue.h"
|
||||
#include "nsIContentPolicy.h"
|
||||
#include "nsIContentSecurityPolicy.h"
|
||||
#include "nsIURI.h"
|
||||
|
||||
@ -441,7 +442,8 @@ nsStyleUtil::IsSignificantChild(nsIContent* aChild, bool aTextIsSignificant,
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
nsStyleUtil::CSPAllowsInlineStyle(nsIPrincipal* aPrincipal,
|
||||
nsStyleUtil::CSPAllowsInlineStyle(nsIContent* aContent,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsIURI* aSourceURI,
|
||||
uint32_t aLineNumber,
|
||||
const nsSubstring& aStyleText,
|
||||
@ -453,6 +455,10 @@ nsStyleUtil::CSPAllowsInlineStyle(nsIPrincipal* aPrincipal,
|
||||
*aRv = NS_OK;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!aContent || aContent->Tag() == nsGkAtoms::style,
|
||||
"aContent passed to CSPAllowsInlineStyle "
|
||||
"for an element that is not <style>");
|
||||
|
||||
nsCOMPtr<nsIContentSecurityPolicy> csp;
|
||||
rv = aPrincipal->GetCsp(getter_AddRefs(csp));
|
||||
|
||||
@ -463,17 +469,42 @@ nsStyleUtil::CSPAllowsInlineStyle(nsIPrincipal* aPrincipal,
|
||||
}
|
||||
|
||||
if (csp) {
|
||||
bool inlineOK = true;
|
||||
bool reportViolation;
|
||||
rv = csp->GetAllowsInlineStyle(&reportViolation, &inlineOK);
|
||||
bool allowInlineStyle = true;
|
||||
rv = csp->GetAllowsInlineStyle(&reportViolation, &allowInlineStyle);
|
||||
if (NS_FAILED(rv)) {
|
||||
if (aRv)
|
||||
*aRv = rv;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool foundNonce = false;
|
||||
nsAutoString nonce;
|
||||
// If inline styles are allowed ('unsafe-inline'), skip the (irrelevant)
|
||||
// nonce check
|
||||
if (!allowInlineStyle) {
|
||||
// We can only find a nonce if aContent is provided
|
||||
foundNonce = !!aContent &&
|
||||
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::nonce, nonce);
|
||||
if (foundNonce) {
|
||||
// We can overwrite the outparams from GetAllowsInlineStyle because
|
||||
// if the nonce is correct, then we don't want to report the original
|
||||
// inline violation (it has been whitelisted by the nonce), and if
|
||||
// the nonce is incorrect, then we want to return just the specific
|
||||
// "nonce violation" rather than both a "nonce violation" and
|
||||
// a generic "inline violation".
|
||||
rv = csp->GetAllowsNonce(nonce, nsIContentPolicy::TYPE_STYLESHEET,
|
||||
&reportViolation, &allowInlineStyle);
|
||||
if (NS_FAILED(rv)) {
|
||||
if (aRv)
|
||||
*aRv = rv;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (reportViolation) {
|
||||
// Inline styles are not allowed by CSP, so report the violation
|
||||
// This inline style is not allowed by CSP, so report the violation
|
||||
nsAutoCString asciiSpec;
|
||||
aSourceURI->GetAsciiSpec(asciiSpec);
|
||||
nsAutoString styleText(aStyleText);
|
||||
@ -481,18 +512,23 @@ nsStyleUtil::CSPAllowsInlineStyle(nsIPrincipal* aPrincipal,
|
||||
// cap the length of the style sample at 40 chars.
|
||||
if (styleText.Length() > 40) {
|
||||
styleText.Truncate(40);
|
||||
styleText.Append(NS_LITERAL_STRING("..."));
|
||||
styleText.AppendLiteral("...");
|
||||
}
|
||||
|
||||
csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_INLINE_STYLE,
|
||||
NS_ConvertUTF8toUTF16(asciiSpec),
|
||||
aStyleText,
|
||||
aLineNumber);
|
||||
// The type of violation to report is determined by whether there was
|
||||
// a nonce present.
|
||||
unsigned short violationType = foundNonce ?
|
||||
nsIContentSecurityPolicy::VIOLATION_TYPE_NONCE_STYLE :
|
||||
nsIContentSecurityPolicy::VIOLATION_TYPE_INLINE_STYLE;
|
||||
csp->LogViolationDetails(violationType, NS_ConvertUTF8toUTF16(asciiSpec),
|
||||
styleText, aLineNumber, nonce);
|
||||
}
|
||||
|
||||
if (!inlineOK) {
|
||||
// The inline style should be blocked.
|
||||
return false;
|
||||
if (!allowInlineStyle) {
|
||||
NS_ASSERTION(reportViolation,
|
||||
"CSP blocked inline style but is not reporting a violation");
|
||||
// The inline style should be blocked.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// No CSP or a CSP that allows inline styles.
|
||||
|
@ -98,15 +98,32 @@ public:
|
||||
bool aWhitespaceIsSignificant);
|
||||
/*
|
||||
* Does this principal have a CSP that blocks the application of
|
||||
* inline styles ? Returns false if application of the style should
|
||||
* inline styles? Returns false if application of the style should
|
||||
* be blocked.
|
||||
*
|
||||
* Note that the principal passed in here needs to be the principal
|
||||
* of the document, not of the style sheet. The document's principal
|
||||
* is where any Content Security Policy that should be used to
|
||||
* block or allow inline styles will be located.
|
||||
* @param aContent
|
||||
* The <style> element that the caller wants to know whether to honor.
|
||||
* Included to check the nonce attribute if one is provided. Allowed to
|
||||
* be null, if this is for something other than a <style> element (in
|
||||
* which case nonces won't be checked).
|
||||
* @param aPrincipal
|
||||
* The principal of the of the document (*not* of the style sheet).
|
||||
* The document's principal is where any Content Security Policy that
|
||||
* should be used to block or allow inline styles will be located.
|
||||
* @param aSourceURI
|
||||
* URI of document containing inline style (for reporting violations)
|
||||
* @param aLineNumber
|
||||
* Line number of inline style element in the containing document (for
|
||||
* reporting violations)
|
||||
* @param aStyleText
|
||||
* Contents of the inline style element (for reporting violations)
|
||||
* @param aRv
|
||||
* Return error code in case of failure
|
||||
* @return
|
||||
* Does CSP allow application of the specified inline style?
|
||||
*/
|
||||
static bool CSPAllowsInlineStyle(nsIPrincipal* aPrincipal,
|
||||
static bool CSPAllowsInlineStyle(nsIContent* aContent,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsIURI* aSourceURI,
|
||||
uint32_t aLineNumber,
|
||||
const nsSubstring& aStyleText,
|
||||
|
@ -1606,6 +1606,7 @@ pref("security.notification_enable_delay", 500);
|
||||
|
||||
pref("security.csp.enable", true);
|
||||
pref("security.csp.debug", false);
|
||||
pref("security.csp.experimentalEnabled", false);
|
||||
|
||||
// Mixed content blocking
|
||||
pref("security.mixed_content.block_active_content", false);
|
||||
|
@ -1926,7 +1926,8 @@ nsCrypto::GenerateCRMFRequest(JSContext* aContext,
|
||||
csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_EVAL,
|
||||
NS_ConvertASCIItoUTF16(fileName),
|
||||
scriptSample,
|
||||
lineNum);
|
||||
lineNum,
|
||||
EmptyString());
|
||||
}
|
||||
|
||||
if (!evalAllowed) {
|
||||
|
@ -212,6 +212,7 @@
|
||||
"content/base/test/csp/test_CSP_bug916446.html":"observer not working",
|
||||
"content/base/test/csp/test_CSP_bug909029.html":"observer not working",
|
||||
"content/base/test/csp/test_policyuri_regression_from_multipolicy.html":"observer not working",
|
||||
"content/base/test/csp/test_nonce_source.html":"observer not working",
|
||||
|
||||
"content/base/test/test_CrossSiteXHR_origin.html":"https not working, bug 907770",
|
||||
"content/base/test/test_plugin_freezing.html":"",
|
||||
|
Loading…
x
Reference in New Issue
Block a user