Bug 1279139 - require-sri-for needs to govern scriptloading for workers. r=baku
MozReview-Commit-ID: 3m21kbiV5qK
This commit is contained in:
@@ -34,7 +34,14 @@
|
|||||||
|
|
||||||
<p id="black-text">black text</p>
|
<p id="black-text">black text</p>
|
||||||
<script>
|
<script>
|
||||||
window.onload = function() {
|
// this worker should not load,
|
||||||
parent.postMessage("finish", '*');
|
// 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>
|
</script>
|
||||||
|
|||||||
5
dom/security/test/sri/iframe_require-sri-for_no_csp.html
Normal file
5
dom/security/test/sri/iframe_require-sri-for_no_csp.html
Normal 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>
|
||||||
@@ -3,11 +3,16 @@ support-files =
|
|||||||
file_bug_1271796.css
|
file_bug_1271796.css
|
||||||
iframe_require-sri-for_main.html
|
iframe_require-sri-for_main.html
|
||||||
iframe_require-sri-for_main.html^headers^
|
iframe_require-sri-for_main.html^headers^
|
||||||
|
iframe_require-sri-for_no_csp.html
|
||||||
iframe_script_crossdomain.html
|
iframe_script_crossdomain.html
|
||||||
iframe_script_sameorigin.html
|
iframe_script_sameorigin.html
|
||||||
iframe_sri_disabled.html
|
iframe_sri_disabled.html
|
||||||
iframe_style_crossdomain.html
|
iframe_style_crossdomain.html
|
||||||
iframe_style_sameorigin.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
|
||||||
script_crossdomain1.js^headers^
|
script_crossdomain1.js^headers^
|
||||||
script_crossdomain2.js
|
script_crossdomain2.js
|
||||||
|
|||||||
9
dom/security/test/sri/rsf_csp_worker.js
Normal file
9
dom/security/test/sri/rsf_csp_worker.js
Normal 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");
|
||||||
|
}
|
||||||
1
dom/security/test/sri/rsf_csp_worker.js^headers^
Normal file
1
dom/security/test/sri/rsf_csp_worker.js^headers^
Normal file
@@ -0,0 +1 @@
|
|||||||
|
content-security-policy: require-sri-for script style
|
||||||
1
dom/security/test/sri/rsf_imported.js
Normal file
1
dom/security/test/sri/rsf_imported.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
postMessage('bad_worker_could_load_via_importScripts');
|
||||||
3
dom/security/test/sri/rsf_spawn_CSPd_worker.js
Normal file
3
dom/security/test/sri/rsf_spawn_CSPd_worker.js
Normal 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;
|
||||||
2
dom/security/test/sri/rsf_worker.js
Normal file
2
dom/security/test/sri/rsf_worker.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
parent.postMessage('bad_worker_could_load', '*');
|
||||||
|
importScripts('rsf_imported.js');
|
||||||
@@ -10,10 +10,12 @@
|
|||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1265318">Mozilla Bug 1265318</a>
|
<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>
|
<iframe style="width:200px;height:200px;" id="test_frame"></iframe><br>
|
||||||
|
<iframe style="width:200px;height:200px;" id="test_frame_no_csp"></iframe>
|
||||||
</body>
|
</body>
|
||||||
<script type="application/javascript">
|
<script type="application/javascript">
|
||||||
|
var finished = 0;
|
||||||
SpecialPowers.setBoolPref("security.csp.experimentalEnabled", true);
|
SpecialPowers.setBoolPref("security.csp.experimentalEnabled", true);
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
function handler(event) {
|
function handler(event) {
|
||||||
@@ -33,12 +35,29 @@
|
|||||||
case 'good_svg_nonsriBlocked':
|
case 'good_svg_nonsriBlocked':
|
||||||
ok(true, 'Eligible non-SRI svg script was correctly blocked by the CSP.');
|
ok(true, 'Eligible non-SRI svg script was correctly blocked by the CSP.');
|
||||||
break;
|
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':
|
case 'finish':
|
||||||
var blackText = frame.contentDocument.getElementById('black-text');
|
finished++;
|
||||||
var blackTextColor = frame.contentWindow.getComputedStyle(blackText, null).getPropertyValue('color');
|
if (finished > 1) {
|
||||||
ok(blackTextColor == 'rgb(0, 0, 0)', "The second part should not be black.");
|
// need finish message from iframe_require-sri-for_main onload event and
|
||||||
removeEventListener('message', handler);
|
// from iframe_require-sri-for_no_csp, which spawns a Worker
|
||||||
SimpleTest.finish();
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
ok(false, 'Something is wrong here');
|
ok(false, 'Something is wrong here');
|
||||||
@@ -46,7 +65,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
addEventListener("message", handler);
|
addEventListener("message", handler);
|
||||||
|
// This frame has a CSP that requires SRI
|
||||||
var frame = document.getElementById("test_frame");
|
var frame = document.getElementById("test_frame");
|
||||||
frame.src = "iframe_require-sri-for_main.html";
|
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>
|
</script>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -59,6 +59,7 @@
|
|||||||
#include "mozilla/dom/PromiseNativeHandler.h"
|
#include "mozilla/dom/PromiseNativeHandler.h"
|
||||||
#include "mozilla/dom/Response.h"
|
#include "mozilla/dom/Response.h"
|
||||||
#include "mozilla/dom/ScriptSettings.h"
|
#include "mozilla/dom/ScriptSettings.h"
|
||||||
|
#include "mozilla/dom/SRILogHelper.h"
|
||||||
#include "mozilla/UniquePtr.h"
|
#include "mozilla/UniquePtr.h"
|
||||||
#include "Principal.h"
|
#include "Principal.h"
|
||||||
#include "WorkerHolder.h"
|
#include "WorkerHolder.h"
|
||||||
@@ -1110,6 +1111,25 @@ private:
|
|||||||
aLoadInfo.mURL.Assign(NS_ConvertUTF8toUTF16(filename));
|
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
|
// Update the principal of the worker and its base URI if we just loaded the
|
||||||
// worker's primary script.
|
// worker's primary script.
|
||||||
if (IsMainWorkerScript()) {
|
if (IsMainWorkerScript()) {
|
||||||
@@ -1215,7 +1235,8 @@ private:
|
|||||||
rv = csp->GetReferrerPolicy(&rp, &hasReferrerPolicy);
|
rv = csp->GetReferrerPolicy(&rp, &hasReferrerPolicy);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
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));
|
mWorkerPrivate->SetReferrerPolicy(static_cast<net::ReferrerPolicy>(rp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user