diff --git a/dom/security/nsCSPUtils.cpp b/dom/security/nsCSPUtils.cpp index dbeaf3d93bfd..35e58c05756e 100644 --- a/dom/security/nsCSPUtils.cpp +++ b/dom/security/nsCSPUtils.cpp @@ -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); } diff --git a/dom/security/test/csp/file_bug1505412.sjs b/dom/security/test/csp/file_bug1505412.sjs new file mode 100644 index 000000000000..0205a587f7ac --- /dev/null +++ b/dom/security/test/csp/file_bug1505412.sjs @@ -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; +} diff --git a/dom/security/test/csp/file_bug1505412_chrome.js b/dom/security/test/csp/file_bug1505412_chrome.js new file mode 100644 index 000000000000..ea1bbd6225e9 --- /dev/null +++ b/dom/security/test/csp/file_bug1505412_chrome.js @@ -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"); diff --git a/dom/security/test/csp/file_bug1505412_frame.html b/dom/security/test/csp/file_bug1505412_frame.html new file mode 100644 index 000000000000..b58af5584959 --- /dev/null +++ b/dom/security/test/csp/file_bug1505412_frame.html @@ -0,0 +1,14 @@ + + + + + Bug 1505412 CSP-RO reports violations in inline-scripts with nonce + + + + + + + + + diff --git a/dom/security/test/csp/file_bug1505412_frame.html^headers^ b/dom/security/test/csp/file_bug1505412_frame.html^headers^ new file mode 100644 index 000000000000..744dbfee418a --- /dev/null +++ b/dom/security/test/csp/file_bug1505412_frame.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy-Report-Only: script-src 'nonce-foobar'; report-uri /report/ diff --git a/dom/security/test/csp/mochitest.ini b/dom/security/test/csp/mochitest.ini index ec259fb1d56d..ae682d637600 100644 --- a/dom/security/test/csp/mochitest.ini +++ b/dom/security/test/csp/mochitest.ini @@ -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] diff --git a/dom/security/test/csp/test_bug1505412.html b/dom/security/test/csp/test_bug1505412.html new file mode 100644 index 000000000000..e904371faeb0 --- /dev/null +++ b/dom/security/test/csp/test_bug1505412.html @@ -0,0 +1,56 @@ + + + + + Bug 1505412 CSP-RO reports violations in inline-scripts with nonce + + + + + +

+ + + Test for 1505412 + + + + +