Bug 1505412 - Skip CSP-Nonce check for CSP-Ro+Redirected Channels r=ckerschb

Differential Revision: https://phabricator.services.mozilla.com/D36916

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Sebastian Streich 2019-08-15 15:51:33 +00:00
Родитель 37db1730c6
Коммит 645ecf6d90
7 изменённых файлов: 162 добавлений и 0 удалений

Просмотреть файл

@ -877,6 +877,25 @@ bool nsCSPNonceSrc::permits(nsIURI* aUri, const nsAString& aNonce,
NS_ConvertUTF16toUTF8(aNonce).get()));
}
if (aReportOnly && aWasRedirected && aNonce.IsEmpty()) {
/* Fix for Bug 1505412
* If we land here, we're currently handling a script-preload which got
* redirected. Preloads do not have any info about the nonce assiociated.
* Because of Report-Only the preload passes the 1st CSP-check so the
* preload does not get retried with a nonce attached.
* Currently we're relying on the script-manager to
* provide a fake loadinfo to check the preloads against csp.
* So during HTTPChannel->OnRedirect we cant check csp for this case.
* But as the script-manager already checked the csp,
* a report would already have been send,
* if the nonce didnt match.
* So we can pass the check here for Report-Only Cases.
*/
MOZ_ASSERT(aParserCreated == false,
"Skipping nonce-check is only allowed for Preloads");
return true;
}
// nonces can not be invalidated by strict-dynamic
return mNonce.Equals(aNonce);
}

Просмотреть файл

@ -0,0 +1,37 @@
// https://bugzilla.mozilla.org/show_bug.cgi?id=650386
// This SJS file serves file_redirect_content.html
// with a CSP that will trigger a violation and that will report it
// to file_redirect_report.sjs
//
// This handles 301, 302, 303 and 307 redirects. The HTTP status code
// returned/type of redirect to do comes from the query string
// parameter passed in from the test_bug650386_* files and then also
// uses that value in the report-uri parameter of the CSP
function handleRequest(request, response) {
response.setHeader("Cache-Control", "no-cache", false);
// this gets used in the CSP as part of the report URI.
var redirect = request.queryString;
if (!redirect) {
// if we somehow got some bogus redirect code here,
// do a 302 redirect to the same URL as the report URI
// redirects to - this will fail the test.
var loc =
"http://sub1.test1.example.org/tests/dom/security/test/csp/file_bug1505412.sjs?redirected";
response.setStatusLine("1.1", 302, "Found");
response.setHeader("Location", loc, false);
return;
}
// response.setHeader("content-type", "text/application", false);
// the actual file content.
// this image load will (intentionally) fail due to the CSP policy of default-src: 'self'
// specified by the CSP string above.
var content =
"ok(true,'Did load the redirected Script without throwing a CSP-Violation'); SimpleTest.finish();";
response.write(content);
return;
}

Просмотреть файл

@ -0,0 +1,30 @@
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
Cu.importGlobalProperties(["TextDecoder"]);
var openingObserver = {
observe: function(subject, topic, data) {
sendAsyncMessage("request-found", { subject, topic, data });
// subject should be an nsURI
if (subject.QueryInterface == undefined) {
return;
}
if (topic == "http-on-opening-request") {
var asciiSpec = subject.QueryInterface(Ci.nsIHttpChannel).URI.asciiSpec;
sendAsyncMessage("request-found", asciiSpec);
if (!asciiSpec.includes("report")) {
return;
}
sendAsyncMessage("report-found");
}
},
};
Services.obs.addObserver(openingObserver, "http-on-opening-request");
addMessageListener("finish", function() {
Services.obs.removeObserver(openingObserver, "http-on-opening-request");
});
sendAsyncMessage("proxy-ready");

Просмотреть файл

@ -0,0 +1,14 @@
<!DOCTYPE HTML>
<html>
<head>
<title> Bug 1505412 CSP-RO reports violations in inline-scripts with nonce</title>
<script src="/tests/SimpleTest/SimpleTest.js" nonce="foobar"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<body>
<script src="file_bug1505412.sjs" nonce="foobar"></script>
</body>
</html>

Просмотреть файл

@ -0,0 +1 @@
Content-Security-Policy-Report-Only: script-src 'nonce-foobar'; report-uri /report/

Просмотреть файл

@ -87,6 +87,10 @@ support-files =
file_bug1312272.js
file_bug1312272.html^headers^
file_bug1452037.html
file_bug1505412.sjs
file_bug1505412_chrome.js
file_bug1505412_frame.html
file_bug1505412_frame.html^headers^
file_policyuri_regression_from_multipolicy.html
file_policyuri_regression_from_multipolicy.html^headers^
file_policyuri_regression_from_multipolicy_policy
@ -246,6 +250,7 @@ prefs =
[test_bug802872.html]
[test_bug885433.html]
[test_bug888172.html]
[test_bug1505412.html]
[test_evalscript.html]
[test_evalscript_blocked_by_strict_dynamic.html]
[test_evalscript_allowed_by_strict_dynamic.html]

Просмотреть файл

@ -0,0 +1,56 @@
<!DOCTYPE HTML>
<html>
<head>
<title> Bug 1505412 CSP-RO reports violations in inline-scripts with nonce</title>
<script src="/tests/SimpleTest/SimpleTest.js" nonce="foobar"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1505412">Test for 1505412 </a>
<script class="testbody" type="text/javascript" nonce="foobar">
/* Description of the test:
1: We setup a Proxy that will cause the Test to Fail
if Firefox sends a CSP-Report to /report
2: We Load an iframe with has a Script pointing to
file_bug1505412.sjs
3: The Preloader will fetch the file and Gets redirected
4: If correct, the File should be loaded and no CSP-Report
should be send.
*/
SimpleTest.waitForExplicitFinish();
SimpleTest.requestCompleteLog();
var chromeScriptUrl = SimpleTest.getTestFileURL("file_bug1505412_chrome.js");
var script = SpecialPowers.loadChromeScript(chromeScriptUrl);
script.addMessageListener('proxy-ready', function pr() {
window.addEventListener("load",()=>{
document.querySelector("#target").src = "file_bug1505412_frame.html";
});
});
script.addMessageListener('report-found', function ml(msg) {
ok(false,"A report was triggered");
SimpleTest.finish();
});
SimpleTest.registerCleanupFunction(()=>{
script.sendAsyncMessage("finish");
});
</script>
<iframe id="target" frameborder="0"></iframe>
</body>
</html>