Commit 2451c80e authored by Karan Bhatia's avatar Karan Bhatia Committed by Commit Bot

IsolatedWorldCSP: Enforce CSP checks for fetch in isolated worlds.

Enforce CSP checks for fetch in isolated worlds. Also add tests for fetch usage
in isolated worlds and its interaction with CSP. This also exposes a bug with
the current handling of redirects as far as bypassing the main world CSP is
concerned.

Since the IsolatedWorldCSP feature is disabled by default, this CL will cause
the CSP check to use an empty CSP instead of just bypassing the CSP checks for
isolated worlds. In practice, this should cause no behavior change.

BUG=896041

Change-Id: I4778112e3c5e7f6fcb2f2849eca6ed7ef384f65e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1633531
Auto-Submit: Karan Bhatia <karandeepb@chromium.org>
Reviewed-by: default avatarHiroshige Hayashizaki <hiroshige@chromium.org>
Commit-Queue: Karan Bhatia <karandeepb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#666122}
parent 1ddefa1b
...@@ -543,9 +543,8 @@ void FetchManager::Loader::Start(ExceptionState& exception_state) { ...@@ -543,9 +543,8 @@ void FetchManager::Loader::Start(ExceptionState& exception_state) {
// "- should fetching |request| be blocked as content security returns // "- should fetching |request| be blocked as content security returns
// blocked" // blocked"
if (!ContentSecurityPolicy::ShouldBypassMainWorld(execution_context_) && if (!execution_context_->GetContentSecurityPolicyForWorld()
!execution_context_->GetContentSecurityPolicy()->AllowConnectToSource( ->AllowConnectToSource(fetch_request_data_->Url())) {
fetch_request_data_->Url())) {
// "A network error." // "A network error."
PerformNetworkError( PerformNetworkError(
"Refused to connect to '" + fetch_request_data_->Url().ElidedString() + "Refused to connect to '" + fetch_request_data_->Url().ElidedString() +
......
CONSOLE MESSAGE: line 53: Testing main world. Request should be blocked by main world CSP.
CONSOLE ERROR: line 10: Refused to connect to 'http://127.0.0.1:8000/security/isolatedWorld/resources/access_control_allow_origin.php' because it violates the following Content Security Policy directive: "connect-src 'none'".
CONSOLE ERROR: line 10: Refused to connect to 'http://127.0.0.1:8000/security/isolatedWorld/resources/access_control_allow_origin.php' because it violates the document's Content Security Policy.
CONSOLE MESSAGE: line 30: PASS: Request blocked by CSP as expected.
CONSOLE MESSAGE: line 58: Testing isolated world with no csp. Request should be blocked by main world CSP.
CONSOLE ERROR: Refused to connect to 'http://127.0.0.1:8000/security/isolatedWorld/resources/access_control_allow_origin.php' because it violates the following Content Security Policy directive: "connect-src 'none'".
CONSOLE ERROR: Refused to connect to 'http://127.0.0.1:8000/security/isolatedWorld/resources/access_control_allow_origin.php' because it violates the document's Content Security Policy.
CONSOLE MESSAGE: PASS: Request blocked by CSP as expected.
CONSOLE MESSAGE: line 65: Testing isolated world with permissive csp.
CONSOLE MESSAGE: PASS: Request succeeded as expected.
CONSOLE MESSAGE: line 71: Testing fetch redirect in isolated world with permissive csp.
CONSOLE ERROR: Refused to connect to 'http://127.0.0.1:8000/security/isolatedWorld/resources/access_control_allow_origin.php' because it violates the following Content Security Policy directive: "connect-src 'none'".
CONSOLE MESSAGE: FAIL: Request failed unexpectedly.
CONSOLE MESSAGE: line 78: Testing isolated world with strict csp.
CONSOLE MESSAGE: line 79: internals.runtimeFlags.isolatedWorldCSPEnabled is false
CONSOLE MESSAGE: PASS: Request succeeded as expected.
CONSOLE MESSAGE: line 91: Testing fetch redirect in isolated world with strict csp.
CONSOLE MESSAGE: line 92: internals.runtimeFlags.isolatedWorldCSPEnabled is false
CONSOLE ERROR: Refused to connect to 'http://127.0.0.1:8000/security/isolatedWorld/resources/access_control_allow_origin.php' because it violates the following Content Security Policy directive: "connect-src 'none'".
CONSOLE MESSAGE: FAIL: Request failed unexpectedly.
This tests the interaction of the fetch API run in the isolated world with the isolated world CSP.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="connect-src 'none'">
<script src="resources/isolated-world-fetch-csp.js"></script>
</head>
<body id="body">
<p>
This tests the interaction of the fetch API run in the isolated world
with the isolated world CSP.
</p>
</body>
</html>
<?php
header("Access-Control-Allow-Origin: *");
header("Content-Type: text/plain");
echo "Hello world";
exit;
?>
function testFetch(expectBlocked, redirect) {
let url =
'http://127.0.0.1:8000/security/isolatedWorld/resources/access_control_allow_origin.php';
if (redirect) {
url = `http://127.0.0.1:8000/resources/redirect.php?url=${
url}&cors_allow_origin=*&delay=100`;
}
fetch(url)
.then(function(response) {
return response.text();
})
.then(function(responseText) {
const success = responseText == 'Hello world';
if (expectBlocked) {
console.log(
'FAIL: Request succeeded unexpectedly with response ' +
responseText);
} else if (!success) {
console.log(
'FAIL: Request succeeded with incorrect response ' +
responseText);
} else {
console.log('PASS: Request succeeded as expected.');
}
})
.catch(function(error) {
if (expectBlocked)
console.log('PASS: Request blocked by CSP as expected.');
else
console.log('FAIL: Request failed unexpectedly.');
})
.finally(function() {
window.postMessage('next', '*');
});
}
const isolatedWorldId = 1;
const isolatedWorldSecurityOrigin = 'chrome-extensions://123';
function testFetchInIsolatedWorld(expectBlocked, redirect) {
const expectBlockedStr = expectBlocked ? 'true' : 'false';
const redirectStr = redirect ? 'true' : 'false';
testRunner.evaluateScriptInIsolatedWorld(
isolatedWorldId,
String(eval('testFetch')) +
`\ntestFetch(${expectBlockedStr}, ${redirectStr});`);
}
const tests = [
function() {
console.log(
'Testing main world. Request should be blocked by main world CSP.');
testFetch(true);
},
function() {
console.log(
'Testing isolated world with no csp. Request should be blocked by ' +
'main world CSP.');
testRunner.setIsolatedWorldInfo(isolatedWorldId, null, null);
testFetchInIsolatedWorld(true);
},
function() {
console.log('Testing isolated world with permissive csp.');
testRunner.setIsolatedWorldInfo(
isolatedWorldId, isolatedWorldSecurityOrigin, 'connect-src *');
testFetchInIsolatedWorld(false);
},
function() {
console.log(
'Testing fetch redirect in isolated world with permissive csp.');
testRunner.setIsolatedWorldInfo(
isolatedWorldId, isolatedWorldSecurityOrigin, 'connect-src *');
testFetchInIsolatedWorld(false, true /* redirect */);
},
function() {
console.log('Testing isolated world with strict csp.');
console.log(
'internals.runtimeFlags.isolatedWorldCSPEnabled is ' +
internals.runtimeFlags.isolatedWorldCSPEnabled);
const expectBlocked = internals.runtimeFlags.isolatedWorldCSPEnabled;
testRunner.setIsolatedWorldInfo(
isolatedWorldId, isolatedWorldSecurityOrigin, 'connect-src \'self\'');
testFetchInIsolatedWorld(expectBlocked);
// Clear the isolated world data.
testRunner.setIsolatedWorldInfo(1, null, null);
},
function() {
console.log('Testing fetch redirect in isolated world with strict csp.');
console.log(
'internals.runtimeFlags.isolatedWorldCSPEnabled is ' +
internals.runtimeFlags.isolatedWorldCSPEnabled);
const expectBlocked = internals.runtimeFlags.isolatedWorldCSPEnabled;
testRunner.setIsolatedWorldInfo(
isolatedWorldId, isolatedWorldSecurityOrigin, 'connect-src \'self\'');
testFetchInIsolatedWorld(expectBlocked, true /* redirect */);
// Clear the isolated world data.
testRunner.setIsolatedWorldInfo(1, null, null);
},
];
// This test is meaningless without testRunner.
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.waitUntilDone();
let currentTest = 0;
window.addEventListener('message', function(e) {
if (e.data == 'next') {
// Move to the next test.
currentTest++;
if (currentTest == tests.length) {
testRunner.notifyDone();
return;
}
// Move to the next sub-test.
tests[currentTest]();
}
}, false);
tests[0]();
}
CONSOLE MESSAGE: line 53: Testing main world. Request should be blocked by main world CSP.
CONSOLE ERROR: line 10: Refused to connect to 'http://127.0.0.1:8000/security/isolatedWorld/resources/access_control_allow_origin.php' because it violates the following Content Security Policy directive: "connect-src 'none'".
CONSOLE ERROR: line 10: Refused to connect to 'http://127.0.0.1:8000/security/isolatedWorld/resources/access_control_allow_origin.php' because it violates the document's Content Security Policy.
CONSOLE MESSAGE: line 30: PASS: Request blocked by CSP as expected.
CONSOLE MESSAGE: line 58: Testing isolated world with no csp. Request should be blocked by main world CSP.
CONSOLE ERROR: Refused to connect to 'http://127.0.0.1:8000/security/isolatedWorld/resources/access_control_allow_origin.php' because it violates the following Content Security Policy directive: "connect-src 'none'".
CONSOLE ERROR: Refused to connect to 'http://127.0.0.1:8000/security/isolatedWorld/resources/access_control_allow_origin.php' because it violates the document's Content Security Policy.
CONSOLE MESSAGE: PASS: Request blocked by CSP as expected.
CONSOLE MESSAGE: line 65: Testing isolated world with permissive csp.
CONSOLE MESSAGE: PASS: Request succeeded as expected.
CONSOLE MESSAGE: line 71: Testing fetch redirect in isolated world with permissive csp.
CONSOLE ERROR: Refused to connect to 'http://127.0.0.1:8000/security/isolatedWorld/resources/access_control_allow_origin.php' because it violates the following Content Security Policy directive: "connect-src 'none'".
CONSOLE MESSAGE: FAIL: Request failed unexpectedly.
CONSOLE MESSAGE: line 78: Testing isolated world with strict csp.
CONSOLE MESSAGE: line 79: internals.runtimeFlags.isolatedWorldCSPEnabled is true
CONSOLE ERROR: Refused to connect to 'http://127.0.0.1:8000/security/isolatedWorld/resources/access_control_allow_origin.php' because it violates the following Content Security Policy directive: "connect-src 'self'".
CONSOLE ERROR: Refused to connect to 'http://127.0.0.1:8000/security/isolatedWorld/resources/access_control_allow_origin.php' because it violates the document's Content Security Policy.
CONSOLE MESSAGE: PASS: Request blocked by CSP as expected.
CONSOLE MESSAGE: line 91: Testing fetch redirect in isolated world with strict csp.
CONSOLE MESSAGE: line 92: internals.runtimeFlags.isolatedWorldCSPEnabled is true
CONSOLE ERROR: Refused to connect to 'http://127.0.0.1:8000/resources/redirect.php?url=http://127.0.0.1:8000/security/isolatedWorld/resources/access_control_allow_origin.php&cors_allow_origin=*&delay=100' because it violates the following Content Security Policy directive: "connect-src 'self'".
CONSOLE ERROR: Refused to connect to 'http://127.0.0.1:8000/resources/redirect.php?url=http://127.0.0.1:8000/security/isolatedWorld/resources/access_control_allow_origin.php&cors_allow_origin=*&delay=100' because it violates the document's Content Security Policy.
CONSOLE MESSAGE: PASS: Request blocked by CSP as expected.
This tests the interaction of the fetch API run in the isolated world with the isolated world CSP.
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