Bug 902654 - refactor CSP call sites for readability r=dholbert r=mrbkap

This commit is contained in:
Garrett Robinson 2013-11-11 14:25:55 -08:00
parent 2699bc1b56
commit 72855f7c75
2 changed files with 132 additions and 117 deletions

View File

@ -412,6 +412,72 @@ ParseTypeAttribute(const nsAString& aType, JSVersion* aVersion)
return true; return true;
} }
bool
CSPAllowsInlineScript(nsIScriptElement *aElement, nsIDocument *aDocument)
{
nsCOMPtr<nsIContentSecurityPolicy> csp;
nsresult rv = aDocument->NodePrincipal()->GetCsp(getter_AddRefs(csp));
NS_ENSURE_SUCCESS(rv, false);
if (!csp) {
// no CSP --> allow
return true;
}
bool reportViolation = false;
bool allowInlineScript = true;
rv = csp->GetAllowsInlineScript(&reportViolation, &allowInlineScript);
NS_ENSURE_SUCCESS(rv, false);
bool foundNonce = false;
nsAutoString nonce;
if (!allowInlineScript) {
nsCOMPtr<nsIContent> scriptContent = do_QueryInterface(aElement);
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 = aDocument->GetDocumentURI();
nsAutoCString asciiSpec;
uri->GetAsciiSpec(asciiSpec);
nsAutoString scriptText;
aElement->GetScriptText(scriptText);
// cap the length of the script sample at 40 chars
if (scriptText.Length() > 40) {
scriptText.Truncate(40);
scriptText.AppendLiteral("...");
}
// 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 (!allowInlineScript) {
NS_ASSERTION(reportViolation,
"CSP blocked inline script but is not reporting a violation");
return false;
}
return true;
}
bool bool
nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement) nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
{ {
@ -619,63 +685,9 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
return false; return false;
} }
nsCOMPtr<nsIContentSecurityPolicy> csp; // Does CSP allow this inline script to run?
rv = mDocument->NodePrincipal()->GetCsp(getter_AddRefs(csp)); if (!CSPAllowsInlineScript(aElement, mDocument)) {
NS_ENSURE_SUCCESS(rv, false); return false;
if (csp) {
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);
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;
uri->GetAsciiSpec(asciiSpec);
nsAutoString scriptText;
aElement->GetScriptText(scriptText);
// cap the length of the script sample at 40 chars
if (scriptText.Length() > 40) {
scriptText.Truncate(40);
scriptText.AppendLiteral("...");
}
// 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 (!allowInlineScript) {
NS_ASSERTION(reportViolation,
"CSP blocked inline script but is not reporting a violation");
return false;
}
} }
// Inline scripts ignore ther CORS mode and are always CORS_NONE // Inline scripts ignore ther CORS mode and are always CORS_NONE

View File

@ -468,69 +468,72 @@ nsStyleUtil::CSPAllowsInlineStyle(nsIContent* aContent,
return false; return false;
} }
if (csp) { if (!csp) {
bool reportViolation; // No CSP --> the style is allowed
bool allowInlineStyle = true; return true;
rv = csp->GetAllowsInlineStyle(&reportViolation, &allowInlineStyle); }
if (NS_FAILED(rv)) {
if (aRv)
*aRv = rv;
return false;
}
bool foundNonce = false; bool reportViolation;
nsAutoString nonce; bool allowInlineStyle = true;
// If inline styles are allowed ('unsafe-inline'), skip the (irrelevant) rv = csp->GetAllowsInlineStyle(&reportViolation, &allowInlineStyle);
// nonce check if (NS_FAILED(rv)) {
if (!allowInlineStyle) { if (aRv)
// We can only find a nonce if aContent is provided *aRv = rv;
foundNonce = !!aContent && return false;
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::nonce, nonce); }
if (foundNonce) {
// We can overwrite the outparams from GetAllowsInlineStyle because bool foundNonce = false;
// if the nonce is correct, then we don't want to report the original nsAutoString nonce;
// inline violation (it has been whitelisted by the nonce), and if // If inline styles are allowed ('unsafe-inline'), skip the (irrelevant)
// the nonce is incorrect, then we want to return just the specific // nonce check
// "nonce violation" rather than both a "nonce violation" and if (!allowInlineStyle) {
// a generic "inline violation". // We can only find a nonce if aContent is provided
rv = csp->GetAllowsNonce(nonce, nsIContentPolicy::TYPE_STYLESHEET, foundNonce = !!aContent &&
&reportViolation, &allowInlineStyle); aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::nonce, nonce);
if (NS_FAILED(rv)) { if (foundNonce) {
if (aRv) // We can overwrite the outparams from GetAllowsInlineStyle because
*aRv = rv; // if the nonce is correct, then we don't want to report the original
return false; // 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) {
// This inline style is not allowed by CSP, so report the violation
nsAutoCString asciiSpec;
aSourceURI->GetAsciiSpec(asciiSpec);
nsAutoString styleText(aStyleText);
// cap the length of the style sample at 40 chars.
if (styleText.Length() > 40) {
styleText.Truncate(40);
styleText.AppendLiteral("...");
}
// 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 (!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.
if (reportViolation) {
// This inline style is not allowed by CSP, so report the violation
nsAutoCString asciiSpec;
aSourceURI->GetAsciiSpec(asciiSpec);
nsAutoString styleText(aStyleText);
// cap the length of the style sample at 40 chars.
if (styleText.Length() > 40) {
styleText.Truncate(40);
styleText.AppendLiteral("...");
}
// 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 (!allowInlineStyle) {
NS_ASSERTION(reportViolation,
"CSP blocked inline style but is not reporting a violation");
// The inline style should be blocked.
return false;
}
// CSP allows inline styles.
return true; return true;
} }