Bug 808292 - CSP: Implement path-level host-source matching, redirect tests (r=grobinson,sstamm)
authorChristoph Kerschbaumer <mozilla@christophkerschbaumer.com>
Wed, 13 Aug 2014 13:04:31 -0700
changeset 230484 9a5ca02006f77040974436d872cc396499f7c482
parent 230483 31d8c9d1a0c394b18a09152203d91cebe88e9c40
child 230485 caf6c61b1ea0fee6277eea212ce0dc2a70036197
push id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-beta@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgrobinson, sstamm
bugs808292
milestone35.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 808292 - CSP: Implement path-level host-source matching, redirect tests (r=grobinson,sstamm)
content/base/test/csp/file_csp_path_matching_redirect.html
content/base/test/csp/file_csp_path_matching_redirect_server.sjs
content/base/test/csp/mochitest.ini
content/base/test/csp/test_csp_path_matching_redirect.html
new file mode 100644
--- /dev/null
+++ b/content/base/test/csp/file_csp_path_matching_redirect.html
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML>
+<html>
+  <head>
+    <title>Bug 808292 - Implement path-level host-source matching to CSP</title>
+  </head>
+  <body>
+  <div id="testdiv">blocked</div>
+  <script src="http://example.com/tests/content/base/test/csp/file_csp_path_matching_redirect_server.sjs"></script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/base/test/csp/file_csp_path_matching_redirect_server.sjs
@@ -0,0 +1,13 @@
+// Redirect server specifically to handle redirects
+// for path-level host-source matching
+// see https://bugzilla.mozilla.org/show_bug.cgi?id=808292
+
+function handleRequest(request, response)
+{
+
+  var newLocation = "http://test1.example.com/tests/content/base/test/csp/file_csp_path_matching.js";
+
+  response.setStatusLine("1.1", 302, "Found");
+  response.setHeader("Cache-Control", "no-cache", false);
+  response.setHeader("Location", newLocation, false);
+}
--- a/content/base/test/csp/mochitest.ini
+++ b/content/base/test/csp/mochitest.ini
@@ -78,16 +78,18 @@ support-files =
   file_CSP_bug941404_xhr.html
   file_CSP_bug941404_xhr.html^headers^
   file_hash_source.html
   file_hash_source.html^headers^
   file_self_none_as_hostname_confusion.html
   file_self_none_as_hostname_confusion.html^headers^
   file_csp_path_matching.html
   file_csp_path_matching.js
+  file_csp_path_matching_redirect.html
+  file_csp_path_matching_redirect_server.sjs
   file_csp_testserver.sjs
   file_report_uri_missing_in_report_only_header.html
   file_report_uri_missing_in_report_only_header.html^headers^
   file_csp_report.html
   file_redirect_content.sjs
   file_redirect_report.sjs
   file_subframe_run_js_if_allowed.html
   file_subframe_run_js_if_allowed.html^headers^
@@ -117,16 +119,17 @@ skip-if = (buildapp == 'b2g' && (toolkit
 [test_policyuri_regression_from_multipolicy.html]
 [test_nonce_source.html]
 [test_CSP_bug941404.html]
 [test_hash_source.html]
 skip-if = e10s || buildapp == 'b2g' # can't compute hashes in child process (bug 958702)
 [test_self_none_as_hostname_confusion.html]
 [test_bug949549.html]
 [test_csp_path_matching.html]
+[test_csp_path_matching_redirect.html]
 [test_report_uri_missing_in_report_only_header.html]
 [test_csp_report.html]
 skip-if = e10s || buildapp == 'b2g' # http-on-opening-request observer not supported in child process (bug 1009632)
 [test_301_redirect.html]
 skip-if = buildapp == 'b2g' # intermittent orange (bug 1028490)
 [test_302_redirect.html]
 skip-if = buildapp == 'b2g' # intermittent orange (bug 1028490)
 [test_303_redirect.html]
new file mode 100644
--- /dev/null
+++ b/content/base/test/csp/test_csp_path_matching_redirect.html
@@ -0,0 +1,89 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Bug 808292 - Implement path-level host-source matching to CSP (redirects)</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>
+  <p id="display"></p>
+  <div id="content" style="visibility: hidden">
+    <iframe style="width:100%;" id="testframe"></iframe>
+  </div>
+
+<script class="testbody" type="text/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+/* Description of the test:
+ * First, we try to load a script where the *path* does not match.
+ * Second, we try to load a script which is allowed by the CSPs
+ * script-src directive. The script then gets redirected to
+ * an URL where the host matches, but the path wouldn't.
+ * Since 'paths' should not be taken into account after redirects,
+ * that load should succeed. We are using a similar test setup
+ * as described in the spec, see:
+ * http://www.w3.org/TR/CSP11/#source-list-paths-and-redirects
+ */
+
+var policy = "script-src http://example.com http://test1.example.com/CSPAllowsScriptsInThatFolder";
+
+var tests = [
+  {
+    // the script in file_csp_path_matching.html
+    // <script src="http://test1.example.com/tests/content/base/..">
+    // is not within the whitelisted path by the csp-policy
+    // hence the script is 'blocked' by CSP.
+    expected: "blocked",
+    uri: "tests/content/base/test/csp/file_csp_path_matching.html"
+  },
+  {
+    // the script in file_csp_path_matching_redirect.html
+    // <script src="http://example.com/tests/content/..">
+    // gets redirected to: http://test1.example.com/tests/content
+    // where after the redirect the path of the policy is not enforced
+    // anymore and hence execution of the script is 'allowed'.
+    expected: "allowed",
+    uri: "tests/content/base/test/csp/file_csp_path_matching_redirect.html"
+  },
+];
+
+var counter = 0;
+var curTest;
+
+function checkResult() {
+  try {
+    document.getElementById("testframe").removeEventListener('load', checkResult, false);
+    var testframe = document.getElementById("testframe");
+    var divcontent = testframe.contentWindow.document.getElementById('testdiv').innerHTML;
+    is(divcontent, curTest.expected, "should be blocked in test " + (counter - 1) + "!");
+  }
+  catch (e) {
+    ok(false, "ERROR: could not access content in test " + (counter - 1) + "!");
+  }
+  loadNextTest();
+}
+
+function loadNextTest() {
+  if (counter == tests.length) {
+    SimpleTest.finish();
+  }
+  else {
+    curTest = tests[counter++];
+    var src = "file_csp_testserver.sjs";
+    // append the file that should be served
+    src += "?file=" + escape(curTest.uri);
+    // append the CSP that should be used to serve the file
+    src += "&csp=" + escape(policy);
+
+    document.getElementById("testframe").addEventListener("load", checkResult, false);
+    document.getElementById("testframe").src = src;
+  }
+}
+
+loadNextTest();
+
+</script>
+</body>
+</html>