diff --git a/content/base/src/nsScriptLoader.cpp b/content/base/src/nsScriptLoader.cpp index 4d92be0b33b..e8f51510f67 100644 --- a/content/base/src/nsScriptLoader.cpp +++ b/content/base/src/nsScriptLoader.cpp @@ -412,6 +412,72 @@ ParseTypeAttribute(const nsAString& aType, JSVersion* aVersion) return true; } +bool +CSPAllowsInlineScript(nsIScriptElement *aElement, nsIDocument *aDocument) +{ + nsCOMPtr 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 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 nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement) { @@ -619,63 +685,9 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement) return false; } - nsCOMPtr csp; - rv = mDocument->NodePrincipal()->GetCsp(getter_AddRefs(csp)); - NS_ENSURE_SUCCESS(rv, 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; - } + // Does CSP allow this inline script to run? + if (!CSPAllowsInlineScript(aElement, mDocument)) { + return false; } // Inline scripts ignore ther CORS mode and are always CORS_NONE diff --git a/layout/style/nsStyleUtil.cpp b/layout/style/nsStyleUtil.cpp index 925b8b71a2a..faa268f238f 100644 --- a/layout/style/nsStyleUtil.cpp +++ b/layout/style/nsStyleUtil.cpp @@ -468,69 +468,72 @@ nsStyleUtil::CSPAllowsInlineStyle(nsIContent* aContent, return false; } - if (csp) { - bool reportViolation; - bool allowInlineStyle = true; - rv = csp->GetAllowsInlineStyle(&reportViolation, &allowInlineStyle); - if (NS_FAILED(rv)) { - if (aRv) - *aRv = rv; - return false; - } + if (!csp) { + // No CSP --> the style is allowed + return true; + } - 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; - } + bool reportViolation; + 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) { - // 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; }