Commit 02b4622b authored by Andy Paicu's avatar Andy Paicu Committed by Commit Bot

Ensure eval flag is properly transfered to context from CSPRO

When setting the eval flag for a worker context, report only policies
were treated as enforcing. Because AllowEval with supress reporting
does not take into account the ReportOnly state of the policy because
it calls CheckEval directly.

AllowEval: https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/frame/csp/content_security_policy.cc?g=0&l=603

CheckEval is called here: https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc?g=0&l=712

Bug: 777076
Change-Id: I80994553037d29c9301aff1ea845386c776c6837
Reviewed-on: https://chromium-review.googlesource.com/c/1301439
Commit-Queue: Andy Paicu <andypaicu@chromium.org>
Reviewed-by: default avatarMike West <mkwst@chromium.org>
Cr-Commit-Position: refs/heads/master@{#605289}
parent c7175f46
<!DOCTYPE HTML>
<html>
<head>
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
</head>
<body>
<!-- This tests that a report only policy is not treated as enforcing when
inherited by a worker. This manifests in particular for `unsafe-eval`
in this bug crbug.com/777076 -->
<script nonce="abc">
var t1 = async_test("Check that inline is allowed since the inherited policy is report only");
var t2 = async_test("Check that eval is allowed since the inherited policy is report only");
var w = new Worker("support/eval.js");
w.onmessage = function(e) {
if (e.data == "unsafe-inline allowed") t1.done();
else if (e.data == "unsafe-eval allowed") t2.done();
}
</script>
</body>
</html>
postMessage('unsafe-inline allowed');
eval("postMessage('unsafe-eval allowed')");
<html>
<head>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<!-- Content-Security-Policy-Report-Only: script-src 'unsafe-inline'; report-uri ../support/report.py?op=put&reportID={{$id}} -->
</head>
<body>
<script>
var t = async_test("Eval is allowed because the CSP is report-only");
try {
eval("t.done()");
} catch {
t.step(function() { assert_true(false, "The eval should have execute succesfully"); })
}
</script>
<script async defer src="../support/checkReport.sub.js?reportField=violated-directive&reportValue=script-src%20%27unsafe-inline%27"></script>
</body>
</html>
Set-Cookie: eval-allowed-in-report-only-mode-and-sends-report={{$id:uuid()}}; Path=/content-security-policy/script-src
Content-Security-Policy-Report-Only: script-src 'unsafe-inline'; report-uri ../support/report.py?op=put&reportID={{$id}}
<html>
<head>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<!-- Content-Security-Policy-Report-Only: script-src 'unsafe-inline' -->
</head>
<body>
<script>
var t = async_test("Eval is allowed because the CSP is report-only");
try {
eval("t.done()");
} catch {
t.step(function() { assert_true(false, "The eval should have execute succesfully"); })
}
</script>
</body>
</html>
CONSOLE ERROR: line 12: [Report Only] Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' 'unsafe-inline'".
ALERT: PASS: eval() allowed!
CSP report received:
CONTENT_TYPE: application/csp-report
HTTP_REFERER: http://127.0.0.1:8000/security/contentSecurityPolicy/eval-allowed-in-report-only-mode-and-sends-report.php
REQUEST_METHOD: POST
=== POST DATA ===
{"csp-report":{"document-uri":"http://127.0.0.1:8000/security/contentSecurityPolicy/eval-allowed-in-report-only-mode-and-sends-report.php","referrer":"","violated-directive":"script-src","effective-directive":"script-src","original-policy":"script-src 'self' 'unsafe-inline'; report-uri resources/save-report.php?test=eval-allowed-in-report-only-mode-and-sends-report.php","disposition":"report","blocked-uri":"eval","line-number":12,"column-number":13,"source-file":"http://127.0.0.1:8000/security/contentSecurityPolicy/eval-allowed-in-report-only-mode-and-sends-report.php","status-code":200,"script-sample":""}}
<?php
header("Content-Security-Policy-Report-Only: script-src 'self' 'unsafe-inline'; report-uri resources/save-report.php?test=eval-allowed-in-report-only-mode-and-sends-report.php");
?>
<!DOCTYPE html>
<html>
<head>
<script>
if (window.internals)
internals.settings.setExperimentalContentSecurityPolicyFeaturesEnabled(false);
</script>
</head>
<body>
<script>
try {
eval("alert('PASS: eval() allowed!')");
} catch (e) {
console.log('FAIL: eval() blocked!');
}
</script>
<script src="resources/go-to-echo-report.js"></script>
</body>
</html>
CONSOLE ERROR: The Content Security Policy 'script-src 'self' 'unsafe-inline'' was delivered in report-only mode, but does not specify a 'report-uri'; the policy will have no effect. Please either add a 'report-uri' directive, or deliver the policy via the 'Content-Security-Policy' header.
CONSOLE ERROR: line 12: [Report Only] Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' 'unsafe-inline'".
ALERT: PASS: eval() executed as expected.
<?php
header("Content-Security-Policy-Report-Only: script-src 'self' 'unsafe-inline'");
?>
<!DOCTYPE html>
<html>
<head>
<script>
if (window.testRunner)
testRunner.dumpAsText();
</script>
</head>
<body>
<script>
try {
eval("alert('PASS: eval() executed as expected.');");
} catch(e) {
alert("FAIL: eval() threw an exception.");
}
</script>
</body>
</html>
...@@ -709,8 +709,9 @@ bool CSPDirectiveList::AllowEval( ...@@ -709,8 +709,9 @@ bool CSPDirectiveList::AllowEval(
"Policy directive: ", "Policy directive: ",
script_state, exception_status, content); script_state, exception_status, content);
} }
return CheckEval( return IsReportOnly() ||
OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrc)); CheckEval(OperativeDirective(
ContentSecurityPolicy::DirectiveType::kScriptSrc));
} }
bool CSPDirectiveList::AllowWasmEval( bool CSPDirectiveList::AllowWasmEval(
...@@ -726,8 +727,9 @@ bool CSPDirectiveList::AllowWasmEval( ...@@ -726,8 +727,9 @@ bool CSPDirectiveList::AllowWasmEval(
"Content Security Policy directive: ", "Content Security Policy directive: ",
script_state, exception_status, content); script_state, exception_status, content);
} }
return CheckWasmEval( return IsReportOnly() ||
OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrc)); CheckWasmEval(OperativeDirective(
ContentSecurityPolicy::DirectiveType::kScriptSrc));
} }
bool CSPDirectiveList::AllowPluginType( bool CSPDirectiveList::AllowPluginType(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment