Bug 1224225: Tests for punycode/unicode in CSP source matching code r=ckerscb draft
authorFrederik Braun <fbraun+gh@mozilla.com>
Wed, 15 Mar 2017 13:22:55 +0100
changeset 499927 580339be6a5d0a2bf00ecf6dabff8d6a8ff1423d
parent 499926 725163deba14e014201c55fc1e5b9b040476f549
child 549520 b2c501c996deac64c94200c94b3165cd239a310c
push id49593
push userbmo:fbraun@mozilla.com
push dateThu, 16 Mar 2017 13:21:29 +0000
reviewersckerscb
bugs1224225
milestone55.0a1
Bug 1224225: Tests for punycode/unicode in CSP source matching code r=ckerscb MozReview-Commit-ID: 21Mr9ekUvnk
dom/security/test/csp/file_punycode_host_src.js
dom/security/test/csp/file_punycode_host_src.sjs
dom/security/test/csp/mochitest.ini
dom/security/test/csp/test_punycode_host_src.html
dom/security/test/gtest/TestCSPParser.cpp
new file mode 100644
--- /dev/null
+++ b/dom/security/test/csp/file_punycode_host_src.js
@@ -0,0 +1,2 @@
+const LOADED = true;
+parent.postMessage({result: 'script-allowed'}, "*");
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/dom/security/test/csp/file_punycode_host_src.sjs
@@ -0,0 +1,45 @@
+// custom *.sjs for Bug 1224225
+// Punycode in CSP host sources
+
+const HTML_PART1 =
+  "<!DOCTYPE HTML>" +
+  "<html><head><meta charset=\"utf-8\">" +
+  "<title>Bug 1224225 - CSP source matching should work for punycoded domain names</title>" +
+  "</head>" +
+  "<body>" +
+  "<script id='script' src='";
+
+const TESTCASE1 = "http://sub2.ält.example.org/";
+const TESTCASE2 = "http://sub2.xn--lt-uia.example.org/"
+
+const HTML_PART2 = "tests/dom/security/test/csp/file_punycode_host_src.js'></script>" +
+  "</body>" +
+  "</html>";
+
+function handleRequest(request, response)
+{
+  // avoid confusing cache behaviors
+  response.setHeader("Cache-Control", "no-cache", false);
+  response.setHeader("Content-Type", "text/html", false);
+
+  Components.utils.importGlobalProperties(["URLSearchParams"]);
+  const query = new URLSearchParams(request.queryString);
+
+
+  if (query.get("csp")) {
+    response.setHeader("Content-Security-Policy", query.get("csp"), false);
+  }
+  if (query.get("action") == "script-unicode-csp-punycode") {
+    response.write(HTML_PART1 + TESTCASE1 + HTML_PART2);
+    return
+  }
+  if (query.get("action") == "script-punycode-csp-punycode") {
+    response.write(HTML_PART1 + TESTCASE2 + HTML_PART2);
+    return
+  }
+
+
+  // we should never get here, but just in case
+  // return something unexpected
+  response.write("do'h");
+}
--- a/dom/security/test/csp/mochitest.ini
+++ b/dom/security/test/csp/mochitest.ini
@@ -198,16 +198,18 @@ support-files =
   file_strict_dynamic_parser_inserted_doc_write.html
   file_strict_dynamic_parser_inserted_doc_write_correct_nonce.html
   file_strict_dynamic_non_parser_inserted.html
   file_strict_dynamic_non_parser_inserted_inline.html
   file_strict_dynamic_unsafe_eval.html
   file_strict_dynamic_default_src.html
   file_strict_dynamic_default_src.js
   file_upgrade_insecure_navigation.sjs
+  file_punycode_host_src.sjs
+  file_punycode_host_src.js
 
 [test_base-uri.html]
 [test_blob_data_schemes.html]
 [test_connect-src.html]
 [test_CSP.html]
 [test_allow_https_schemes.html]
 [test_bug663567.html]
 [test_bug802872.html]
@@ -285,8 +287,9 @@ tags = mcb
 [test_sendbeacon.html]
 [test_upgrade_insecure_docwrite_iframe.html]
 [test_bug1242019.html]
 [test_bug1312272.html]
 [test_strict_dynamic.html]
 [test_strict_dynamic_parser_inserted.html]
 [test_strict_dynamic_default_src.html]
 [test_upgrade_insecure_navigation.html]
+[test_punycode_host_src.html]
new file mode 100644
--- /dev/null
+++ b/dom/security/test/csp/test_punycode_host_src.html
@@ -0,0 +1,81 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Bug 1224225 - CSP source matching should work for punycoded domain names</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>
+<iframe style="width:100%;" id="testframe"></iframe>
+
+<script class="testbody" type="text/javascript">
+
+/* Description of the test:
+ * We load scripts within an iframe and make sure that the
+ * CSP matching is same for punycode domain names as well as IDNA.
+ */
+
+SimpleTest.waitForExplicitFinish();
+
+
+var curTest;
+var counter = -1;
+
+const tests = [
+  { // test 1
+    description: "loads script as sub2.ält.example.org, but whitelist in CSP as sub2.xn--lt-uia.example.org",
+    action: "script-unicode-csp-punycode",
+    csp: "script-src http://sub2.xn--lt-uia.example.org;",
+    expected: "script-allowed",
+
+  },
+  { // test 2
+    description: "loads script as sub2.xn--lt-uia.example.org, and whitelist in CSP as sub2.xn--lt-uia.example.org",
+    action: "script-punycode-csp-punycode",
+    csp: "script-src http://sub2.xn--lt-uia.example.org;",
+    expected: "script-allowed",
+
+  },
+    { // test 3
+    description: "loads script as sub2.xn--lt-uia.example.org, and whitelist in CSP as sub2.xn--lt-uia.example.org",
+    action: "script-punycode-csp-punycode",
+    csp: "script-src *.xn--lt-uia.example.org;",
+    expected: "script-allowed",
+
+  },
+
+];
+
+function finishTest() {
+  window.removeEventListener("message", receiveMessage);
+  SimpleTest.finish();
+}
+
+function checkResults(result) {
+  is(result, curTest.expected, curTest.description);
+  loadNextTest();
+}
+
+window.addEventListener("message", receiveMessage);
+function receiveMessage(event) {
+  checkResults(event.data.result);
+}
+
+function loadNextTest() {
+  counter++;
+  if (counter == tests.length) {
+    finishTest();
+    return;
+  }
+  curTest = tests[counter];
+  var testframe = document.getElementById("testframe");
+  testframe.src = `file_punycode_host_src.sjs?action=${curTest.action}&csp=${curTest.csp}`;
+}
+
+loadNextTest();
+
+</script>
+</body>
+</html>
--- a/dom/security/test/gtest/TestCSPParser.cpp
+++ b/dom/security/test/gtest/TestCSPParser.cpp
@@ -199,16 +199,18 @@ nsresult runTestSuite(const PolicyTest* 
 }
 
 // ============================= TestDirectives ========================
 
 TEST(CSPParser, Directives)
 {
   static const PolicyTest policies[] =
   {
+    { "connect-src xn--mnchen-3ya.de",
+      "connect-src http://xn--mnchen-3ya.de"},
     { "default-src http://www.example.com",
       "default-src http://www.example.com" },
     { "script-src http://www.example.com",
       "script-src http://www.example.com" },
     { "object-src http://www.example.com",
       "object-src http://www.example.com" },
     { "style-src http://www.example.com",
       "style-src http://www.example.com" },