Bug 1279139 - require-sri-for needs to govern scriptloading for workers. r=baku

MozReview-Commit-ID: 3m21kbiV5qK
This commit is contained in:
Frederik Braun
2016-10-04 02:36:00 +02:00
parent 3f52f9d79d
commit c20f81e63d
10 changed files with 88 additions and 10 deletions

View File

@@ -34,7 +34,14 @@
<p id="black-text">black text</p>
<script>
window.onload = function() {
// this worker should not load,
// given that we can not provide integrity metadata through the constructor
w = new Worker("rsf_worker.js");
w.onerror = function(e) {
if (typeof w == "object") {
parent.postMessage("finish", '*');
} else {
parent.postMessage("error", "*")
}
}
</script>

View File

@@ -0,0 +1,5 @@
<script>
w = new Worker("rsf_csp_worker.js");
// use the handler function in the parent frame (test_require-sri-for_csp_directive.html)
w.onmessage = parent.handler;
</script>

View File

@@ -3,11 +3,16 @@ support-files =
file_bug_1271796.css
iframe_require-sri-for_main.html
iframe_require-sri-for_main.html^headers^
iframe_require-sri-for_no_csp.html
iframe_script_crossdomain.html
iframe_script_sameorigin.html
iframe_sri_disabled.html
iframe_style_crossdomain.html
iframe_style_sameorigin.html
rsf_csp_worker.js
rsf_csp_worker.js^headers^
rsf_imported.js
rsf_worker.js
script_crossdomain1.js
script_crossdomain1.js^headers^
script_crossdomain2.js

View File

@@ -0,0 +1,9 @@
postMessage("good_worker_could_load");
try {
importScripts('rsf_imported.js');
} catch(e) {
postMessage("good_worker_after_importscripts");
}
finally {
postMessage("finish");
}

View File

@@ -0,0 +1 @@
content-security-policy: require-sri-for script style

View File

@@ -0,0 +1 @@
postMessage('bad_worker_could_load_via_importScripts');

View File

@@ -0,0 +1,3 @@
w = new Worker("rsf_csp_worker.js");
// use the handler function in test_require-sri-for_csp_directive.html
w.onmessage = parent.handler;

View File

@@ -0,0 +1,2 @@
parent.postMessage('bad_worker_could_load', '*');
importScripts('rsf_imported.js');

View File

@@ -10,10 +10,12 @@
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1265318">Mozilla Bug 1265318</a>
<iframe style="width:200px;height:200px;" id="test_frame"></iframe>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1265318">Mozilla Bug 1265318</a><br>
<iframe style="width:200px;height:200px;" id="test_frame"></iframe><br>
<iframe style="width:200px;height:200px;" id="test_frame_no_csp"></iframe>
</body>
<script type="application/javascript">
var finished = 0;
SpecialPowers.setBoolPref("security.csp.experimentalEnabled", true);
SimpleTest.waitForExplicitFinish();
function handler(event) {
@@ -33,12 +35,29 @@
case 'good_svg_nonsriBlocked':
ok(true, 'Eligible non-SRI svg script was correctly blocked by the CSP.');
break;
case 'bad_worker_could_load':
ok(false, 'require-sri-for failed to block loading a Worker with no integrity metadata.');
break;
case 'good_worker_could_load':
ok(true, "Loaded a worker that has require-sri-for set (but its parent doesnt).")
break;
case 'bad_worker_could_load_via_importScripts':
ok(false, 'require-sri-for failed to block loading importScript in a worker though we require SRI via CSP');
break;
case 'good_worker_after_importscripts':
ok(true, 'Worker continued after failed importScript due to require-sri-for');
break;
case 'finish':
finished++;
if (finished > 1) {
// need finish message from iframe_require-sri-for_main onload event and
// from iframe_require-sri-for_no_csp, which spawns a Worker
var blackText = frame.contentDocument.getElementById('black-text');
var blackTextColor = frame.contentWindow.getComputedStyle(blackText, null).getPropertyValue('color');
ok(blackTextColor == 'rgb(0, 0, 0)', "The second part should not be black.");
removeEventListener('message', handler);
SimpleTest.finish();
}
break;
default:
ok(false, 'Something is wrong here');
@@ -46,7 +65,12 @@
}
}
addEventListener("message", handler);
// This frame has a CSP that requires SRI
var frame = document.getElementById("test_frame");
frame.src = "iframe_require-sri-for_main.html";
// This frame has no CSP to require SRI.
// Used for testing require-sri-for in a Worker.
var frame_no_csp = document.getElementById("test_frame_no_csp");
frame_no_csp.src = "iframe_require-sri-for_no_csp.html";
</script>
</html>

View File

@@ -59,6 +59,7 @@
#include "mozilla/dom/PromiseNativeHandler.h"
#include "mozilla/dom/Response.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/SRILogHelper.h"
#include "mozilla/UniquePtr.h"
#include "Principal.h"
#include "WorkerHolder.h"
@@ -1110,6 +1111,25 @@ private:
aLoadInfo.mURL.Assign(NS_ConvertUTF8toUTF16(filename));
}
nsCOMPtr<nsILoadInfo> chanLoadInfo = channel->GetLoadInfo();
if (chanLoadInfo && chanLoadInfo->GetEnforceSRI()) {
// importScripts() and the Worker constructor do not support integrity metadata
// (or any fetch options). Until then, we can just block.
// If we ever have those data in the future, we'll have to the check to
// by using the SRICheck module
MOZ_LOG(SRILogHelper::GetSriLog(), mozilla::LogLevel::Debug,
("Scriptloader::Load, SRI required but not supported in workers"));
nsCOMPtr<nsIContentSecurityPolicy> wcsp;
chanLoadInfo->LoadingPrincipal()->GetCsp(getter_AddRefs(wcsp));
MOZ_ASSERT(wcsp, "We sould have a CSP for the worker here");
if (wcsp) {
wcsp->LogViolationDetails(
nsIContentSecurityPolicy::VIOLATION_TYPE_REQUIRE_SRI_FOR_SCRIPT,
aLoadInfo.mURL, EmptyString(), 0, EmptyString(), EmptyString());
}
return NS_ERROR_SRI_CORRUPT;
}
// Update the principal of the worker and its base URI if we just loaded the
// worker's primary script.
if (IsMainWorkerScript()) {
@@ -1215,7 +1235,8 @@ private:
rv = csp->GetReferrerPolicy(&rp, &hasReferrerPolicy);
NS_ENSURE_SUCCESS(rv, rv);
if (hasReferrerPolicy) {
if (hasReferrerPolicy) { //FIXME bug 1307366: move RP out of CSP code
mWorkerPrivate->SetReferrerPolicy(static_cast<net::ReferrerPolicy>(rp));
}
}