зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1223647: CSP erroneously inherited into dedicated workers. r=ckerschb
--HG-- rename : dom/workers/test/serviceworkers/test_eval_not_allowed.html^headers^ => dom/workers/test/serviceworkers/test_eval_allowed.html^headers^
This commit is contained in:
Родитель
01d0bafa52
Коммит
27c89ea082
|
@ -6614,22 +6614,6 @@ nsContentUtils::FindInternalContentViewer(const nsACString& aType,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
nsContentUtils::GetContentSecurityPolicy(nsIContentSecurityPolicy** aCSP)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
nsCOMPtr<nsIContentSecurityPolicy> csp;
|
||||
nsresult rv = SubjectPrincipal()->GetCsp(getter_AddRefs(csp));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("CSP: Failed to get CSP from principal.");
|
||||
return false;
|
||||
}
|
||||
|
||||
csp.forget(aCSP);
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
nsContentUtils::IsPatternMatching(nsAString& aValue, nsAString& aPattern,
|
||||
|
|
|
@ -522,11 +522,6 @@ public:
|
|||
return sSecurityManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ContentSecurityPolicy for a JS context.
|
||||
**/
|
||||
static bool GetContentSecurityPolicy(nsIContentSecurityPolicy** aCSP);
|
||||
|
||||
// Returns the subject principal. Guaranteed to return non-null. May only
|
||||
// be called when nsContentUtils is initialized.
|
||||
static nsIPrincipal* SubjectPrincipal();
|
||||
|
|
|
@ -1690,8 +1690,10 @@ nsXMLHttpRequest::Open(const nsACString& inMethod, const nsACString& url,
|
|||
nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
|
||||
}
|
||||
|
||||
// If we have the document, use it
|
||||
if (doc) {
|
||||
// If we have the document, use it. Unfortunately, for dedicated workers
|
||||
// 'doc' ends up being the parent document, which is not the document
|
||||
// that we want to use. So make sure to avoid using 'doc' in that situation.
|
||||
if (doc && doc->NodePrincipal() == mPrincipal) {
|
||||
rv = NS_NewChannel(getter_AddRefs(mChannel),
|
||||
uri,
|
||||
doc,
|
||||
|
|
|
@ -1 +1 @@
|
|||
Content-Security-Policy: default-src 'self' ; style-src 'unsafe-inline' 'self'
|
||||
Content-Security-Policy: default-src 'self' blob: ; style-src 'unsafe-inline' 'self'
|
||||
|
|
|
@ -1,16 +1,28 @@
|
|||
// some javascript for the CSP XHR tests
|
||||
//
|
||||
function doXHR(uri) {
|
||||
try {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", uri);
|
||||
xhr.send();
|
||||
} catch(ex) {}
|
||||
}
|
||||
|
||||
doXHR("http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs?testid=xhr_good");
|
||||
doXHR("http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid=xhr_bad");
|
||||
fetch("http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs?testid=fetch_good");
|
||||
fetch("http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid=fetch_bad");
|
||||
navigator.sendBeacon("http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs?testid=beacon_good");
|
||||
try {
|
||||
var xhr_good = new XMLHttpRequest();
|
||||
var xhr_good_uri ="http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs?testid=xhr_good";
|
||||
xhr_good.open("GET", xhr_good_uri, true);
|
||||
xhr_good.send(null);
|
||||
} catch(e) {}
|
||||
navigator.sendBeacon("http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid=beacon_bad");
|
||||
} catch(ex) {}
|
||||
|
||||
try {
|
||||
var xhr_bad = new XMLHttpRequest();
|
||||
var xhr_bad_uri ="http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid=xhr_bad";
|
||||
xhr_bad.open("GET", xhr_bad_uri, true);
|
||||
xhr_bad.send(null);
|
||||
} catch(e) {}
|
||||
|
||||
new Worker("file_main_worker.js").postMessage({inherited : false});
|
||||
|
||||
|
||||
var blobxhr = new XMLHttpRequest();
|
||||
blobxhr.open("GET", "file_main_worker.js")
|
||||
blobxhr.responseType = "blob";
|
||||
blobxhr.send();
|
||||
blobxhr.onload = () => {
|
||||
new Worker(URL.createObjectURL(blobxhr.response)).postMessage({inherited : true});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
function doXHR(uri) {
|
||||
try {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", uri);
|
||||
xhr.send();
|
||||
} catch(ex) {}
|
||||
}
|
||||
|
||||
var sameBase = "http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs?testid=";
|
||||
var crossBase = "http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid=";
|
||||
|
||||
onmessage = (e) => {
|
||||
for (base of [sameBase, crossBase]) {
|
||||
var prefix;
|
||||
var suffix;
|
||||
if (e.data.inherited) {
|
||||
prefix = base + "worker_inherited_"
|
||||
suffix = base == sameBase ? "_good" : "_bad";
|
||||
}
|
||||
else {
|
||||
prefix = base + "worker_"
|
||||
suffix = base == sameBase ? "_same_good" : "_cross_good";
|
||||
}
|
||||
doXHR(prefix + "xhr" + suffix);
|
||||
fetch(prefix + "fetch" + suffix);
|
||||
try { importScripts(prefix + "script" + suffix); } catch(ex) {}
|
||||
}
|
||||
}
|
|
@ -11,17 +11,18 @@ var thisSite = "http://mochi.test:8888";
|
|||
var otherSite = "http://example.com";
|
||||
var page = "/tests/dom/security/test/csp/file_redirects_page.sjs";
|
||||
|
||||
var tests = { "font-src": thisSite+page+"?testid=font-src&csp=1",
|
||||
"frame-src": thisSite+page+"?testid=frame-src&csp=1",
|
||||
"img-src": thisSite+page+"?testid=img-src&csp=1",
|
||||
"media-src": thisSite+page+"?testid=media-src&csp=1",
|
||||
"object-src": thisSite+page+"?testid=object-src&csp=1",
|
||||
"script-src": thisSite+page+"?testid=script-src&csp=1",
|
||||
"style-src": thisSite+page+"?testid=style-src&csp=1",
|
||||
"worker": thisSite+page+"?testid=worker&csp=1",
|
||||
"xhr-src": thisSite+page+"?testid=xhr-src&csp=1",
|
||||
"script-src-from-worker": thisSite+page+"?testid=script-src-from-worker&csp=1",
|
||||
"img-src-from-css": thisSite+page+"?testid=img-src-from-css&csp=1",
|
||||
var tests = { "font-src": thisSite+page+"?testid=font-src",
|
||||
"frame-src": thisSite+page+"?testid=frame-src",
|
||||
"img-src": thisSite+page+"?testid=img-src",
|
||||
"media-src": thisSite+page+"?testid=media-src",
|
||||
"object-src": thisSite+page+"?testid=object-src",
|
||||
"script-src": thisSite+page+"?testid=script-src",
|
||||
"style-src": thisSite+page+"?testid=style-src",
|
||||
"worker": thisSite+page+"?testid=worker",
|
||||
"xhr-src": thisSite+page+"?testid=xhr-src",
|
||||
"from-worker": thisSite+page+"?testid=from-worker",
|
||||
"from-blob-worker": thisSite+page+"?testid=from-blob-worker",
|
||||
"img-src-from-css": thisSite+page+"?testid=img-src-from-css",
|
||||
};
|
||||
|
||||
var container = document.getElementById("container");
|
||||
|
|
|
@ -14,15 +14,13 @@ function handleRequest(request, response)
|
|||
var resource = "/tests/dom/security/test/csp/file_redirects_resource.sjs";
|
||||
|
||||
// CSP header value
|
||||
if (query["csp"] == 1) {
|
||||
var additional = ""
|
||||
if (query['testid'] == "worker") {
|
||||
additional = "; script-src 'self' 'unsafe-inline'";
|
||||
}
|
||||
response.setHeader("Content-Security-Policy",
|
||||
"default-src 'self' ; style-src 'self' 'unsafe-inline'" + additional,
|
||||
false);
|
||||
var additional = ""
|
||||
if (query['testid'] == "worker") {
|
||||
additional = "; script-src 'self' 'unsafe-inline'";
|
||||
}
|
||||
response.setHeader("Content-Security-Policy",
|
||||
"default-src 'self' blob: ; style-src 'self' 'unsafe-inline'" + additional,
|
||||
false);
|
||||
|
||||
// downloadable font that redirects to another site
|
||||
if (query["testid"] == "font-src") {
|
||||
|
@ -90,13 +88,27 @@ function handleRequest(request, response)
|
|||
return;
|
||||
}
|
||||
|
||||
if (query["testid"] == "script-src-from-worker") {
|
||||
if (query["testid"] == "from-worker") {
|
||||
// loads a script; launches a worker; that worker uses importscript; which then gets redirected
|
||||
// So it's:
|
||||
// <script "res=loadWorkerThatImports">
|
||||
// .. loads Worker("res=importScriptWorker")
|
||||
// <script src="res=loadWorkerThatMakesRequests">
|
||||
// .. loads Worker("res=makeRequestsWorker")
|
||||
// .. calls importScript("res=script")
|
||||
response.write('<script src="'+resource+'?res=loadWorkerThatImports&id=script-src-redir-from-worker"></script>');
|
||||
// .. calls xhr("res=xhr-resp")
|
||||
// .. calls fetch("res=xhr-resp")
|
||||
response.write('<script src="'+resource+'?res=loadWorkerThatMakesRequests&id=from-worker"></script>');
|
||||
return;
|
||||
}
|
||||
|
||||
if (query["testid"] == "from-blob-worker") {
|
||||
// loads a script; launches a worker; that worker uses importscript; which then gets redirected
|
||||
// So it's:
|
||||
// <script src="res=loadBlobWorkerThatMakesRequests">
|
||||
// .. loads Worker("res=makeRequestsWorker")
|
||||
// .. calls importScript("res=script")
|
||||
// .. calls xhr("res=xhr-resp")
|
||||
// .. calls fetch("res=xhr-resp")
|
||||
response.write('<script src="'+resource+'?res=loadBlobWorkerThatMakesRequests&id=from-blob-worker"></script>');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,29 +102,45 @@ function handleRequest(request, response)
|
|||
|
||||
// script that loads an internal worker that uses importScripts on a redirect
|
||||
// to an external script.
|
||||
if (query["res"] == "loadWorkerThatImports") {
|
||||
if (query["res"] == "loadWorkerThatMakesRequests") {
|
||||
// this creates a worker (same origin) that imports a redirecting script.
|
||||
let workerURL = thisSite + resource + '?res=importScriptWorker&id=' + query["id"];
|
||||
let workerURL = thisSite + resource + '?res=makeRequestsWorker&id=' + query["id"];
|
||||
response.setHeader("Content-Type", "application/javascript", false);
|
||||
response.write("var w=new Worker('" + workerURL + "'); w.onmessage=function(event){ alert(event.data); }");
|
||||
response.write("new Worker('" + workerURL + "');");
|
||||
return;
|
||||
}
|
||||
|
||||
// script that loads an internal worker that uses importScripts on a redirect
|
||||
// to an external script.
|
||||
if (query["res"] == "loadBlobWorkerThatMakesRequests") {
|
||||
// this creates a worker (same origin) that imports a redirecting script.
|
||||
let workerURL = thisSite + resource + '?res=makeRequestsWorker&id=' + query["id"];
|
||||
response.setHeader("Content-Type", "application/javascript", false);
|
||||
response.write("var x = new XMLHttpRequest(); x.open('GET', '" + workerURL + "'); ");
|
||||
response.write("x.responseType = 'blob'; x.send(); ");
|
||||
response.write("x.onload = () => { new Worker(URL.createObjectURL(x.response)); };");
|
||||
return;
|
||||
}
|
||||
|
||||
// source for a worker that simply calls importScripts on a script that
|
||||
// redirects.
|
||||
if (query["res"] == "importScriptWorker") {
|
||||
if (query["res"] == "makeRequestsWorker") {
|
||||
// this is code for a worker that imports a redirected script.
|
||||
let scriptURL = thisSite + resource + "?redir=other&res=script&id=" + query["id"];
|
||||
let scriptURL = thisSite + resource + "?redir=other&res=script&id=script-src-redir-" + query["id"];
|
||||
let xhrURL = thisSite + resource + "?redir=other&res=xhr-resp&id=xhr-src-redir-" + query["id"];
|
||||
let fetchURL = thisSite + resource + "?redir=other&res=xhr-resp&id=fetch-src-redir-" + query["id"];
|
||||
response.setHeader("Content-Type", "application/javascript", false);
|
||||
response.write("importScripts('" + scriptURL + "');");
|
||||
response.write("try { importScripts('" + scriptURL + "'); } catch(ex) {} ");
|
||||
response.write("var x = new XMLHttpRequest(); x.open('GET', '" + xhrURL + "'); x.send();");
|
||||
response.write("fetch('" + fetchURL + "');");
|
||||
return;
|
||||
}
|
||||
|
||||
// script that invokes XHR
|
||||
if (query["res"] == "xhr") {
|
||||
response.setHeader("Content-Type", "application/javascript", false);
|
||||
var resp = 'var x = new XMLHttpRequest();x.open("GET", "' + otherSite +
|
||||
resource+'?res=xhr-resp&testid=xhr-src-redir", false);\n' +
|
||||
var resp = 'var x = new XMLHttpRequest();x.open("GET", "' + thisSite +
|
||||
resource+'?redir=other&res=xhr-resp&id=xhr-src-redir", false);\n' +
|
||||
'x.send(null);';
|
||||
response.write(resp);
|
||||
return;
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 949706 - CSP: Correct handling of web workers importing scripts that get redirected</title>
|
||||
</head>
|
||||
<body>
|
||||
<script src="file_worker_redirect.sjs?stage_0_script_loads_worker"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,37 +0,0 @@
|
|||
// testserver customized for the needs of:
|
||||
// Bug 949706 - CSP: Correct handling of web workers importing scripts that get redirected
|
||||
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
|
||||
var query = request.queryString;
|
||||
|
||||
if (query === "stage_0_script_loads_worker") {
|
||||
var newWorker =
|
||||
"var myWorker = new Worker(\"file_worker_redirect.sjs?stage_1_worker_import_scripts\");" +
|
||||
"myWorker.onmessage = function (event) { parent.checkResult(\"allowed\"); };" +
|
||||
"myWorker.onerror = function (event) { parent.checkResult(\"blocked\"); };";
|
||||
response.write(newWorker);
|
||||
return;
|
||||
}
|
||||
|
||||
if (query === "stage_1_worker_import_scripts") {
|
||||
response.write("importScripts(\"file_worker_redirect.sjs?stage_2_redirect_imported_script\");");
|
||||
return;
|
||||
}
|
||||
|
||||
if (query === "stage_2_redirect_imported_script") {
|
||||
var newLocation =
|
||||
"http://test1.example.com/tests/dom/security/test/csp/file_worker_redirect.sjs?stage_3_target_script";
|
||||
response.setStatusLine("1.1", 302, "Found");
|
||||
response.setHeader("Location", newLocation, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (query === "stage_3_target_script") {
|
||||
response.write("postMessage(\"imported script loaded\");");
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -40,6 +40,7 @@ support-files =
|
|||
file_main.html
|
||||
file_main.html^headers^
|
||||
file_main.js
|
||||
file_main_worker.js
|
||||
file_web_manifest.html
|
||||
file_web_manifest_remote.html
|
||||
file_web_manifest_https.html
|
||||
|
@ -115,8 +116,6 @@ support-files =
|
|||
file_multi_policy_injection_bypass_2.html^headers^
|
||||
file_null_baseuri.html
|
||||
file_form-action.html
|
||||
file_worker_redirect.html
|
||||
file_worker_redirect.sjs
|
||||
file_referrerdirective.html
|
||||
referrerdirective.sjs
|
||||
file_upgrade_insecure.html
|
||||
|
@ -199,7 +198,6 @@ skip-if = buildapp == 'b2g' # intermittent orange (bug 1028490)
|
|||
[test_referrerdirective.html]
|
||||
skip-if = buildapp == 'b2g' #no ssl support
|
||||
[test_dual_header.html]
|
||||
[test_worker_redirect.html]
|
||||
[test_upgrade_insecure.html]
|
||||
# no ssl support as well as websocket tests do not work (see test_websocket.html)
|
||||
skip-if = buildapp == 'b2g' || buildapp == 'mulet' || toolkit == 'gonk' || toolkit == 'android'
|
||||
|
|
|
@ -25,6 +25,22 @@ window.tests = {
|
|||
script_bad: -1,
|
||||
xhr_good: -1,
|
||||
xhr_bad: -1,
|
||||
fetch_good: -1,
|
||||
fetch_bad: -1,
|
||||
beacon_good: -1,
|
||||
beacon_bad: -1,
|
||||
worker_xhr_same_good: -1,
|
||||
worker_xhr_cross_good: -1,
|
||||
worker_fetch_same_good: -1,
|
||||
worker_fetch_cross_good: -1,
|
||||
worker_script_same_good: -1,
|
||||
worker_script_cross_good: -1,
|
||||
worker_inherited_xhr_good: -1,
|
||||
worker_inherited_xhr_bad: -1,
|
||||
worker_inherited_fetch_good: -1,
|
||||
worker_inherited_fetch_bad: -1,
|
||||
worker_inherited_script_good: -1,
|
||||
worker_inherited_script_bad: -1,
|
||||
media_good: -1,
|
||||
media_bad: -1,
|
||||
font_good: -1,
|
||||
|
@ -81,10 +97,11 @@ examiner.prototype = {
|
|||
window.examiner = new examiner();
|
||||
|
||||
window.testResult = function(testname, result, msg) {
|
||||
//test already complete.... forget it... remember the first result.
|
||||
// test already complete.... forget it... remember the first result.
|
||||
if (window.tests[testname] != -1)
|
||||
return;
|
||||
|
||||
ok(testname in window.tests, "It's a real test");
|
||||
window.tests[testname] = result;
|
||||
is(result, true, testname + ' test: ' + msg);
|
||||
|
||||
|
|
|
@ -86,10 +86,16 @@ var testExpectedResults = { "font-src": true,
|
|||
"worker-redir": false,
|
||||
"xhr-src": true,
|
||||
"xhr-src-redir": false,
|
||||
"script-src-from-worker": true, /* test runs */
|
||||
"script-src-redir-from-worker": false, /* redir is blocked */
|
||||
"img-src-from-css": true, /* test runs */
|
||||
"img-src-redir-from-css": false, /* redir is blocked */
|
||||
"from-worker": true,
|
||||
"script-src-redir-from-worker": true, /* redir is allowed since policy isn't inherited */
|
||||
"xhr-src-redir-from-worker": true, /* redir is allowed since policy isn't inherited */
|
||||
"fetch-src-redir-from-worker": true, /* redir is allowed since policy isn't inherited */
|
||||
"from-blob-worker": true,
|
||||
"script-src-redir-from-blob-worker": false,
|
||||
"xhr-src-redir-from-blob-worker": false,
|
||||
"fetch-src-redir-from-blob-worker": false,
|
||||
"img-src-from-css": true,
|
||||
"img-src-redir-from-css": false,
|
||||
};
|
||||
|
||||
// takes the name of the test, the URL that was tested, and whether the
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 949706 - CSP: Correct handling of web workers importing scripts that get redirected</title>
|
||||
<!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="content" style="visibility: hidden">
|
||||
<iframe style="width:100%;" id="testframe"></iframe>
|
||||
</div>
|
||||
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
/* Description of the test:
|
||||
* We load a page that loads a script which then instantiates a web worker,
|
||||
* where that web worker then imports a script which gets redirected.
|
||||
* We verify that the CSP applies correctly after the imported script of
|
||||
* the worker gets redirected. More specifically, the test works as follows:
|
||||
*
|
||||
* test_worker_redirect.html
|
||||
* -> loads file_worker_redirect.html file into iframe
|
||||
* -> loads worker file_worker_redirect.sjs?stage_0_script_loads_worker
|
||||
* -> creates script file_worker_redirect.sjs?stage_1_worker_import_scripts
|
||||
* -> redirects script file_worker_redirect.sjs?stage_2_redirect_imported_script
|
||||
* -> loads target script file_worker_redirect.sjs?stage_3_target_script
|
||||
*
|
||||
* Please note that we have to use 'unsafe-eval' in the policy
|
||||
* so that workers are actually permitted by the CSP.
|
||||
*
|
||||
* The main test is loaded using:
|
||||
* http://mochi.test:8888
|
||||
* where the imported script gets redirected to:
|
||||
* http://test1.example.com
|
||||
*/
|
||||
|
||||
var tests = [
|
||||
{
|
||||
policy: "default-src 'self'; script-src 'self' 'unsafe-eval'; child-src 'self' http://test1.example.com;",
|
||||
expected: "allowed"
|
||||
},
|
||||
{
|
||||
policy: "default-src 'self'; script-src 'self' 'unsafe-eval'; child-src 'self';",
|
||||
expected: "blocked",
|
||||
},
|
||||
];
|
||||
|
||||
var counter = 0;
|
||||
var curTest;
|
||||
|
||||
function checkResult(aResult) {
|
||||
is(aResult, curTest.expected, "Should be (" + curTest.expected + ") in Test " + counter + "!");
|
||||
loadNextTest();
|
||||
}
|
||||
|
||||
function loadNextTest() {
|
||||
if (counter == tests.length) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
curTest = tests[counter++];
|
||||
var src = "file_testserver.sjs";
|
||||
// append the file that should be served
|
||||
src += "?file=" + escape("tests/dom/security/test/csp/file_worker_redirect.html");
|
||||
// append the CSP that should be used to serve the file
|
||||
src += "&csp=" + escape(curTest.policy);
|
||||
document.getElementById("testframe").src = src;
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
loadNextTest();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -122,6 +122,14 @@ ChannelFromScriptURL(nsIPrincipal* principal,
|
|||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
// If we have the document, use it. Unfortunately, for dedicated workers
|
||||
// 'parentDoc' ends up being the parent document, which is not the document
|
||||
// that we want to use. So make sure to avoid using 'parentDoc' in that
|
||||
// situation.
|
||||
if (parentDoc && parentDoc->NodePrincipal() != principal) {
|
||||
parentDoc = nullptr;
|
||||
}
|
||||
|
||||
int16_t shouldLoad = nsIContentPolicy::ACCEPT;
|
||||
rv = NS_CheckContentLoadPolicy(aContentPolicyType, uri,
|
||||
principal, parentDoc,
|
||||
|
@ -164,8 +172,11 @@ ChannelFromScriptURL(nsIPrincipal* principal,
|
|||
aLoadFlags |= nsIChannel::LOAD_CLASSIFY_URI;
|
||||
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
// If we have the document, use it
|
||||
if (parentDoc) {
|
||||
// If we have the document, use it. Unfortunately, for dedicated workers
|
||||
// 'parentDoc' ends up being the parent document, which is not the document
|
||||
// that we want to use. So make sure to avoid using 'parentDoc' in that
|
||||
// situation.
|
||||
if (parentDoc && parentDoc->NodePrincipal() == principal) {
|
||||
rv = NS_NewChannel(getter_AddRefs(channel),
|
||||
uri,
|
||||
parentDoc,
|
||||
|
|
|
@ -3409,6 +3409,16 @@ WorkerPrivateParent<Derived>::SetPrincipal(nsIPrincipal* aPrincipal,
|
|||
appStatus == nsIPrincipal::APP_STATUS_PRIVILEGED);
|
||||
mLoadInfo.mIsInCertifiedApp = (appStatus == nsIPrincipal::APP_STATUS_CERTIFIED);
|
||||
|
||||
aPrincipal->GetCsp(getter_AddRefs(mLoadInfo.mCSP));
|
||||
|
||||
if (mLoadInfo.mCSP) {
|
||||
mLoadInfo.mCSP->GetAllowsEval(&mLoadInfo.mReportCSPViolations,
|
||||
&mLoadInfo.mEvalAllowed);
|
||||
} else {
|
||||
mLoadInfo.mEvalAllowed = true;
|
||||
mLoadInfo.mReportCSPViolations = false;
|
||||
}
|
||||
|
||||
mLoadInfo.mLoadGroup = aLoadGroup;
|
||||
|
||||
mLoadInfo.mPrincipalInfo = new PrincipalInfo();
|
||||
|
@ -4334,20 +4344,6 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow,
|
|||
MOZ_ASSERT(loadInfo.mPrincipal);
|
||||
MOZ_ASSERT(isChrome || !loadInfo.mDomain.IsEmpty());
|
||||
|
||||
if (!nsContentUtils::GetContentSecurityPolicy(getter_AddRefs(loadInfo.mCSP))) {
|
||||
NS_WARNING("Failed to get CSP!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (loadInfo.mCSP) {
|
||||
rv = loadInfo.mCSP->GetAllowsEval(&loadInfo.mReportCSPViolations,
|
||||
&loadInfo.mEvalAllowed);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
loadInfo.mEvalAllowed = true;
|
||||
loadInfo.mReportCSPViolations = false;
|
||||
}
|
||||
|
||||
if (!loadInfo.mLoadGroup || aLoadGroupBehavior == OverrideLoadGroup) {
|
||||
OverrideLoadInfoLoadGroup(loadInfo);
|
||||
}
|
||||
|
|
|
@ -3,14 +3,26 @@
|
|||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
onmessage = function(event) {
|
||||
if (event.data == 0) {
|
||||
postMessage(eval('40 + 2'));
|
||||
} else if (event.data > 0) {
|
||||
var worker = new Worker('csp_worker.js');
|
||||
worker.postMessage(event.data - 1);
|
||||
} else if (event.data == -1) {
|
||||
importScripts('data:application/javascript;base64,ZHVtcCgnaGVsbG8gd29ybGQnKQo=');
|
||||
} else if (event.data == -2) {
|
||||
importScripts('javascript:dump(123);');
|
||||
if (event.data.do == "eval") {
|
||||
var res;
|
||||
try {
|
||||
res = eval("40+2");
|
||||
}
|
||||
catch(ex) {
|
||||
res = ex+"";
|
||||
}
|
||||
postMessage(res);
|
||||
}
|
||||
else if (event.data.do == "nest") {
|
||||
var worker = new Worker(event.data.uri);
|
||||
if (--event.data.level) {
|
||||
worker.postMessage(event.data);
|
||||
}
|
||||
else {
|
||||
worker.postMessage({ do: "eval" });
|
||||
}
|
||||
worker.onmessage = (e) => {
|
||||
postMessage(e.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -176,7 +176,7 @@ support-files =
|
|||
gzip_redirect_worker.js
|
||||
sw_clients/navigator.html
|
||||
eval_worker.js
|
||||
test_eval_not_allowed.html^headers^
|
||||
test_eval_allowed.html^headers^
|
||||
opaque_intercept_worker.js
|
||||
notify_loaded.js
|
||||
test_request_context.js
|
||||
|
@ -204,7 +204,6 @@ skip-if = release_build
|
|||
[test_cross_origin_url_after_redirect.html]
|
||||
[test_empty_serviceworker.html]
|
||||
[test_eval_allowed.html]
|
||||
[test_eval_not_allowed.html]
|
||||
[test_fetch_event.html]
|
||||
[test_force_refresh.html]
|
||||
[test_gzip_redirect.html]
|
||||
|
|
|
@ -19,9 +19,16 @@
|
|||
}
|
||||
|
||||
function runTest() {
|
||||
try {
|
||||
eval("1");
|
||||
ok(false, "should throw");
|
||||
}
|
||||
catch (ex) {
|
||||
ok(true, "did throw");
|
||||
}
|
||||
register()
|
||||
.then(function(swr) {
|
||||
ok(true, "eval in service worker script didn't cause an issue");
|
||||
ok(true, "eval restriction didn't get inherited");
|
||||
swr.unregister();
|
||||
SimpleTest.finish();
|
||||
}).catch(function(e) {
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1160458 - CSP activated by default in Service Workers</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script class="testbody" type="text/javascript">
|
||||
function register() {
|
||||
return navigator.serviceWorker.register("eval_worker.js");
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
register()
|
||||
.then(function(swr) {
|
||||
ok(false, "eval in service worker should not be allowed when the policy prevents it");
|
||||
swr.unregister();
|
||||
SimpleTest.finish();
|
||||
}).catch(function() {
|
||||
ok(true, "eval in service worker is not allowed when the policy prevents eval");
|
||||
SimpleTest.finish();
|
||||
}).catch(function(e) {
|
||||
ok(false, "Some test failed with error " + e);
|
||||
SimpleTest.finish();
|
||||
});
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true],
|
||||
['dom.serviceWorkers.interception.enabled', true],
|
||||
]}, runTest);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -1,2 +1,2 @@
|
|||
Cache-Control: no-cache
|
||||
Content-Security-Policy: default-src 'self'
|
||||
Content-Security-Policy: default-src 'self' blob:
|
||||
|
|
|
@ -2,49 +2,47 @@
|
|||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
msg = null;
|
||||
var errors = 5;
|
||||
var tests = 3;
|
||||
|
||||
onerror = function(event) {
|
||||
ok(true, msg);
|
||||
if (!--errors) SimpleTest.finish();
|
||||
}
|
||||
|
||||
msg = "No Eval allowed";
|
||||
worker = new Worker("csp_worker.js");
|
||||
worker.postMessage(0);
|
||||
worker.onmessage = function(event) {
|
||||
ok(false, "Eval succeeded!");
|
||||
}
|
||||
|
||||
msg = "No Eval allowed 2";
|
||||
worker = new Worker("csp_worker.js");
|
||||
worker.postMessage(4);
|
||||
worker.onmessage = function(event) {
|
||||
ok(false, "Eval succeeded!");
|
||||
}
|
||||
|
||||
msg = "ImportScripts data:";
|
||||
worker = new Worker("csp_worker.js");
|
||||
worker.postMessage(-1);
|
||||
worker.onmessage = function(event) {
|
||||
ok(false, "Eval succeeded!");
|
||||
}
|
||||
|
||||
msg = "ImportScripts javascript:";
|
||||
worker = new Worker("csp_worker.js");
|
||||
worker.postMessage(-2);
|
||||
worker.onmessage = function(event) {
|
||||
ok(false, "Eval succeeded!");
|
||||
}
|
||||
|
||||
msg = "Loading data:something";
|
||||
try {
|
||||
worker = new Worker("data:application/javascript;base64,ZHVtcCgnaGVsbG8gd29ybGQnKQo=");
|
||||
ok(false, "Should have thrown!");
|
||||
} catch (e) {
|
||||
ok(true, "Threw as expected.");
|
||||
}
|
||||
|
||||
worker = new Worker("javascript:dump(123);");
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
testDone = function(event) {
|
||||
if (!--tests) SimpleTest.finish();
|
||||
}
|
||||
|
||||
// Workers don't inherit CSP
|
||||
worker = new Worker("csp_worker.js");
|
||||
worker.postMessage({ do: "eval" });
|
||||
worker.onmessage = function(event) {
|
||||
is(event.data, 42, "Eval succeeded!");
|
||||
testDone();
|
||||
}
|
||||
|
||||
// blob: workers *do* inherit CSP
|
||||
xhr = new XMLHttpRequest;
|
||||
xhr.open("GET", "csp_worker.js");
|
||||
xhr.responseType = "blob";
|
||||
xhr.send();
|
||||
xhr.onload = (e) => {
|
||||
uri = URL.createObjectURL(e.target.response);
|
||||
worker = new Worker(uri);
|
||||
worker.postMessage({ do: "eval" })
|
||||
worker.onmessage = function(event) {
|
||||
is(event.data, "Error: call to eval() blocked by CSP", "Eval threw");
|
||||
testDone();
|
||||
}
|
||||
}
|
||||
|
||||
xhr = new XMLHttpRequest;
|
||||
xhr.open("GET", "csp_worker.js");
|
||||
xhr.responseType = "blob";
|
||||
xhr.send();
|
||||
xhr.onload = (e) => {
|
||||
uri = URL.createObjectURL(e.target.response);
|
||||
worker = new Worker(uri);
|
||||
worker.postMessage({ do: "nest", uri: uri, level: 3 })
|
||||
worker.onmessage = function(event) {
|
||||
is(event.data, "Error: call to eval() blocked by CSP", "Eval threw in nested worker");
|
||||
testDone();
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче