mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1026520 - CSP: Inline report sending into allows - callsite updates (r=dveditz)
This commit is contained in:
parent
88205c7780
commit
6c324f760e
@ -436,99 +436,21 @@ CSPAllowsInlineScript(nsIScriptElement *aElement, nsIDocument *aDocument)
|
||||
return true;
|
||||
}
|
||||
|
||||
// An inline script can be allowed because all inline scripts are allowed,
|
||||
// or else because it is whitelisted by a nonce-source or hash-source. This
|
||||
// is a logical OR between whitelisting methods, so the allowInlineScript
|
||||
// outparam can be reused for each check as long as we stop checking as soon
|
||||
// as it is set to true. This also optimizes performance by avoiding the
|
||||
// overhead of unnecessary checks.
|
||||
bool allowInlineScript = true;
|
||||
nsAutoTArray<unsigned short, 3> violations;
|
||||
|
||||
bool reportInlineViolation = false;
|
||||
rv = csp->GetAllowsInlineScript(&reportInlineViolation, &allowInlineScript);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
if (reportInlineViolation) {
|
||||
violations.AppendElement(static_cast<unsigned short>(
|
||||
nsIContentSecurityPolicy::VIOLATION_TYPE_INLINE_SCRIPT));
|
||||
}
|
||||
|
||||
// query the nonce
|
||||
nsCOMPtr<nsIContent> scriptContent = do_QueryInterface(aElement);
|
||||
nsAutoString nonce;
|
||||
if (!allowInlineScript) {
|
||||
nsCOMPtr<nsIContent> scriptContent = do_QueryInterface(aElement);
|
||||
bool foundNonce = scriptContent->GetAttr(kNameSpaceID_None,
|
||||
nsGkAtoms::nonce, nonce);
|
||||
if (foundNonce) {
|
||||
bool reportNonceViolation;
|
||||
rv = csp->GetAllowsNonce(nonce, nsIContentPolicy::TYPE_SCRIPT,
|
||||
&reportNonceViolation, &allowInlineScript);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
if (reportNonceViolation) {
|
||||
violations.AppendElement(static_cast<unsigned short>(
|
||||
nsIContentSecurityPolicy::VIOLATION_TYPE_NONCE_SCRIPT));
|
||||
}
|
||||
}
|
||||
}
|
||||
scriptContent->GetAttr(kNameSpaceID_None, nsGkAtoms::nonce, nonce);
|
||||
|
||||
if (!allowInlineScript) {
|
||||
bool reportHashViolation;
|
||||
nsAutoString scriptText;
|
||||
aElement->GetScriptText(scriptText);
|
||||
rv = csp->GetAllowsHash(scriptText, nsIContentPolicy::TYPE_SCRIPT,
|
||||
&reportHashViolation, &allowInlineScript);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
if (reportHashViolation) {
|
||||
violations.AppendElement(static_cast<unsigned short>(
|
||||
nsIContentSecurityPolicy::VIOLATION_TYPE_HASH_SCRIPT));
|
||||
}
|
||||
}
|
||||
// query the scripttext
|
||||
nsAutoString scriptText;
|
||||
aElement->GetScriptText(scriptText);
|
||||
|
||||
// What violation(s) should be reported?
|
||||
//
|
||||
// 1. If the script tag has a nonce attribute, and the nonce does not match
|
||||
// the policy, report VIOLATION_TYPE_NONCE_SCRIPT.
|
||||
// 2. If the policy has at least one hash-source, and the hashed contents of
|
||||
// the script tag did not match any of them, report VIOLATION_TYPE_HASH_SCRIPT
|
||||
// 3. Otherwise, report VIOLATION_TYPE_INLINE_SCRIPT if appropriate.
|
||||
//
|
||||
// 1 and 2 may occur together, 3 should only occur by itself. Naturally,
|
||||
// every VIOLATION_TYPE_NONCE_SCRIPT and VIOLATION_TYPE_HASH_SCRIPT are also
|
||||
// VIOLATION_TYPE_INLINE_SCRIPT, but reporting the
|
||||
// VIOLATION_TYPE_INLINE_SCRIPT is redundant and does not help the developer.
|
||||
if (!violations.IsEmpty()) {
|
||||
MOZ_ASSERT(violations[0] == nsIContentSecurityPolicy::VIOLATION_TYPE_INLINE_SCRIPT,
|
||||
"How did we get any violations without an initial inline script violation?");
|
||||
// gather information to log with violation report
|
||||
nsIURI* uri = aDocument->GetDocumentURI();
|
||||
nsAutoCString asciiSpec;
|
||||
uri->GetAsciiSpec(asciiSpec);
|
||||
nsAutoString scriptText;
|
||||
aElement->GetScriptText(scriptText);
|
||||
nsAutoString scriptSample(scriptText);
|
||||
|
||||
// cap the length of the script sample at 40 chars
|
||||
if (scriptSample.Length() > 40) {
|
||||
scriptSample.Truncate(40);
|
||||
scriptSample.AppendLiteral("...");
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < violations.Length(); i++) {
|
||||
// Skip reporting the redundant inline script violation if there are
|
||||
// other (nonce and/or hash violations) as well.
|
||||
if (i > 0 || violations.Length() == 1) {
|
||||
csp->LogViolationDetails(violations[i], NS_ConvertUTF8toUTF16(asciiSpec),
|
||||
scriptSample, aElement->GetScriptLineNumber(),
|
||||
nonce, scriptText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!allowInlineScript) {
|
||||
NS_ASSERTION(!violations.IsEmpty(),
|
||||
"CSP blocked inline script but is not reporting a violation");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
bool allowInlineScript = false;
|
||||
rv = csp->GetAllowsInline(nsIContentPolicy::TYPE_SCRIPT,
|
||||
nonce, scriptText,
|
||||
aElement->GetScriptLineNumber(),
|
||||
&allowInlineScript);
|
||||
return allowInlineScript;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -722,42 +722,37 @@ EventListenerManager::SetEventHandler(nsIAtom* aName,
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
|
||||
// Perform CSP check
|
||||
nsCOMPtr<nsIContentSecurityPolicy> csp;
|
||||
rv = doc->NodePrincipal()->GetCsp(getter_AddRefs(csp));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (csp) {
|
||||
bool inlineOK = true;
|
||||
bool reportViolations = false;
|
||||
rv = csp->GetAllowsInlineScript(&reportViolations, &inlineOK);
|
||||
// let's generate a script sample and pass it as aContent,
|
||||
// it will not match the hash, but allows us to pass
|
||||
// the script sample in aCOntent.
|
||||
nsAutoString scriptSample, attr, tagName(NS_LITERAL_STRING("UNKNOWN"));
|
||||
aName->ToString(attr);
|
||||
nsCOMPtr<nsIDOMNode> domNode(do_QueryInterface(mTarget));
|
||||
if (domNode) {
|
||||
domNode->GetNodeName(tagName);
|
||||
}
|
||||
// build a "script sample" based on what we know about this element
|
||||
scriptSample.Assign(attr);
|
||||
scriptSample.AppendLiteral(" attribute on ");
|
||||
scriptSample.Append(tagName);
|
||||
scriptSample.AppendLiteral(" element");
|
||||
|
||||
bool allowsInlineScript = true;
|
||||
rv = csp->GetAllowsInline(nsIContentPolicy::TYPE_SCRIPT,
|
||||
EmptyString(), // aNonce
|
||||
scriptSample,
|
||||
0, // aLineNumber
|
||||
&allowsInlineScript);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (reportViolations) {
|
||||
// gather information to log with violation report
|
||||
nsIURI* uri = doc->GetDocumentURI();
|
||||
nsAutoCString asciiSpec;
|
||||
if (uri)
|
||||
uri->GetAsciiSpec(asciiSpec);
|
||||
nsAutoString scriptSample, attr, tagName(NS_LITERAL_STRING("UNKNOWN"));
|
||||
aName->ToString(attr);
|
||||
nsCOMPtr<nsIDOMNode> domNode(do_QueryInterface(mTarget));
|
||||
if (domNode)
|
||||
domNode->GetNodeName(tagName);
|
||||
// build a "script sample" based on what we know about this element
|
||||
scriptSample.Assign(attr);
|
||||
scriptSample.AppendLiteral(" attribute on ");
|
||||
scriptSample.Append(tagName);
|
||||
scriptSample.AppendLiteral(" element");
|
||||
csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_INLINE_SCRIPT,
|
||||
NS_ConvertUTF8toUTF16(asciiSpec),
|
||||
scriptSample,
|
||||
0,
|
||||
EmptyString(),
|
||||
EmptyString());
|
||||
}
|
||||
|
||||
// return early if CSP wants us to block inline scripts
|
||||
if (!inlineOK) {
|
||||
if (!allowsInlineScript) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
@ -178,27 +178,15 @@ nsresult nsJSThunk::EvaluateScript(nsIChannel *aChannel,
|
||||
rv = principal->GetCsp(getter_AddRefs(csp));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (csp) {
|
||||
bool allowsInline = true;
|
||||
bool reportViolations = false;
|
||||
rv = csp->GetAllowsInlineScript(&reportViolations, &allowsInline);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (reportViolations) {
|
||||
// gather information to log with violation report
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
principal->GetURI(getter_AddRefs(uri));
|
||||
nsAutoCString asciiSpec;
|
||||
uri->GetAsciiSpec(asciiSpec);
|
||||
csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_INLINE_SCRIPT,
|
||||
NS_ConvertUTF8toUTF16(asciiSpec),
|
||||
NS_ConvertUTF8toUTF16(mURL),
|
||||
0,
|
||||
EmptyString(),
|
||||
EmptyString());
|
||||
}
|
||||
bool allowsInlineScript = true;
|
||||
rv = csp->GetAllowsInline(nsIContentPolicy::TYPE_SCRIPT,
|
||||
EmptyString(), // aNonce
|
||||
EmptyString(), // aContent
|
||||
0, // aLineNumber
|
||||
&allowsInlineScript);
|
||||
|
||||
//return early if inline scripts are not allowed
|
||||
if (!allowsInline) {
|
||||
if (!allowsInlineScript) {
|
||||
return NS_ERROR_DOM_RETVAL_UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
@ -679,106 +679,17 @@ nsStyleUtil::CSPAllowsInlineStyle(nsIContent* aContent,
|
||||
return true;
|
||||
}
|
||||
|
||||
// An inline style can be allowed because all inline styles are allowed,
|
||||
// or else because it is whitelisted by a nonce-source or hash-source. This
|
||||
// is a logical OR between whitelisting methods, so the allowInlineStyle
|
||||
// outparam can be reused for each check as long as we stop checking as soon
|
||||
// as it is set to true. This also optimizes performance by avoiding the
|
||||
// overhead of unnecessary checks.
|
||||
bool allowInlineStyle = true;
|
||||
nsAutoTArray<unsigned short, 3> violations;
|
||||
|
||||
bool reportInlineViolation;
|
||||
rv = csp->GetAllowsInlineStyle(&reportInlineViolation, &allowInlineStyle);
|
||||
if (NS_FAILED(rv)) {
|
||||
if (aRv)
|
||||
*aRv = rv;
|
||||
return false;
|
||||
}
|
||||
if (reportInlineViolation) {
|
||||
violations.AppendElement(static_cast<unsigned short>(
|
||||
nsIContentSecurityPolicy::VIOLATION_TYPE_INLINE_STYLE));
|
||||
}
|
||||
|
||||
// query the nonce
|
||||
nsAutoString nonce;
|
||||
if (!allowInlineStyle) {
|
||||
// We can only find a nonce if aContent is provided
|
||||
bool foundNonce = !!aContent &&
|
||||
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::nonce, nonce);
|
||||
if (foundNonce) {
|
||||
bool reportNonceViolation;
|
||||
rv = csp->GetAllowsNonce(nonce, nsIContentPolicy::TYPE_STYLESHEET,
|
||||
&reportNonceViolation, &allowInlineStyle);
|
||||
if (NS_FAILED(rv)) {
|
||||
if (aRv)
|
||||
*aRv = rv;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (reportNonceViolation) {
|
||||
violations.AppendElement(static_cast<unsigned short>(
|
||||
nsIContentSecurityPolicy::VIOLATION_TYPE_NONCE_STYLE));
|
||||
}
|
||||
}
|
||||
if (aContent) {
|
||||
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::nonce, nonce);
|
||||
}
|
||||
|
||||
if (!allowInlineStyle) {
|
||||
bool reportHashViolation;
|
||||
rv = csp->GetAllowsHash(aStyleText, nsIContentPolicy::TYPE_STYLESHEET,
|
||||
&reportHashViolation, &allowInlineStyle);
|
||||
if (NS_FAILED(rv)) {
|
||||
if (aRv)
|
||||
*aRv = rv;
|
||||
return false;
|
||||
}
|
||||
if (reportHashViolation) {
|
||||
violations.AppendElement(static_cast<unsigned short>(
|
||||
nsIContentSecurityPolicy::VIOLATION_TYPE_HASH_STYLE));
|
||||
}
|
||||
}
|
||||
bool allowInlineStyle = true;
|
||||
rv = csp->GetAllowsInline(nsIContentPolicy::TYPE_STYLESHEET,
|
||||
nonce, aStyleText, aLineNumber,
|
||||
&allowInlineStyle);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
// What violation(s) should be reported?
|
||||
//
|
||||
// 1. If the style tag has a nonce attribute, and the nonce does not match
|
||||
// the policy, report VIOLATION_TYPE_NONCE_STYLE.
|
||||
// 2. If the policy has at least one hash-source, and the hashed contents of
|
||||
// the style tag did not match any of them, report VIOLATION_TYPE_HASH_STYLE
|
||||
// 3. Otherwise, report VIOLATION_TYPE_INLINE_STYLE if appropriate.
|
||||
//
|
||||
// 1 and 2 may occur together, 3 should only occur by itself. Naturally,
|
||||
// every VIOLATION_TYPE_NONCE_STYLE and VIOLATION_TYPE_HASH_STYLE are also
|
||||
// VIOLATION_TYPE_INLINE_STYLE, but reporting the
|
||||
// VIOLATION_TYPE_INLINE_STYLE is redundant and does not help the developer.
|
||||
if (!violations.IsEmpty()) {
|
||||
MOZ_ASSERT(violations[0] == nsIContentSecurityPolicy::VIOLATION_TYPE_INLINE_STYLE,
|
||||
"How did we get any violations without an initial inline style violation?");
|
||||
// This inline style is not allowed by CSP, so report the violation
|
||||
nsAutoCString asciiSpec;
|
||||
aSourceURI->GetAsciiSpec(asciiSpec);
|
||||
nsAutoString styleSample(aStyleText);
|
||||
|
||||
// cap the length of the style sample at 40 chars.
|
||||
if (styleSample.Length() > 40) {
|
||||
styleSample.Truncate(40);
|
||||
styleSample.AppendLiteral("...");
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < violations.Length(); i++) {
|
||||
// Skip reporting the redundant inline style violation if there are
|
||||
// other (nonce and/or hash violations) as well.
|
||||
if (i > 0 || violations.Length() == 1) {
|
||||
csp->LogViolationDetails(violations[i], NS_ConvertUTF8toUTF16(asciiSpec),
|
||||
styleSample, aLineNumber, nonce, aStyleText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!allowInlineStyle) {
|
||||
NS_ASSERTION(!violations.IsEmpty(),
|
||||
"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 allowInlineStyle;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user