Bug 883975 - Make CSP nonce-source tests for inline resources more precise. r=sstamm
authorGarrett Robinson <grobinson@mozilla.com>
Tue, 14 Jan 2014 09:39:51 -0500
changeset 163329 64712081790e4f1fcb2362b6a32a513e32470987
parent 163328 d570802145c998d4002af2e186f9860c46eb3144
child 163330 5bf95850a0857e4bbf570fc26bc178776d2da8d0
push id25993
push userkwierso@gmail.com
push dateTue, 14 Jan 2014 23:24:56 +0000
treeherdermozilla-central@4e671e3183c4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssstamm
bugs883975
milestone29.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 883975 - Make CSP nonce-source tests for inline resources more precise. r=sstamm
content/base/test/csp/file_nonce_source.html
content/base/test/csp/test_nonce_source.html
--- a/content/base/test/csp/file_nonce_source.html
+++ b/content/base/test/csp/file_nonce_source.html
@@ -4,27 +4,33 @@
     <!-- external styles -->
     <link rel='stylesheet' nonce="correctstylenonce" href="file_CSP.sjs?testid=external_style_correct_nonce_good&type=text/css" />
     <link rel='stylesheet' nonce="incorrectstylenonce" href="file_CSP.sjs?testid=external_style_incorrect_nonce_bad&type=text/css" />
     <link rel='stylesheet' nonce="correctscriptnonce" href="file_CSP.sjs?testid=external_style_correct_script_nonce_bad&type=text/css" />
     <link rel='stylesheet' href="file_CSP.sjs?testid=external_style_no_nonce_bad&type=text/css" />
   </head>
   <body>
     <!-- inline scripts -->
+    <ol>
+      <li id="inline-script-correct-nonce">(inline script with correct nonce) This text should be green.</li>
+      <li id="inline-script-incorrect-nonce">(inline script with incorrect nonce) This text should be black.</li>
+      <li id="inline-script-correct-style-nonce">(inline script with correct nonce for styles, but not for scripts) This text should be black.</li>
+      <li id="inline-script-no-nonce">(inline script with no nonce) This text should be black.</li>
+    </ol>
     <script nonce="correctscriptnonce">
-      window.parent.inlineScriptTestResult("allowed", "allowed", "This script has a correct nonce for scripts");
+      document.getElementById("inline-script-correct-nonce").style.color = "rgb(0, 128, 0)";
     </script>
     <script nonce="incorrectscriptnonce">
-      window.parent.inlineScriptTestResult("allowed", "blocked", "This script has an incorrect nonce for scripts");
+      document.getElementById("inline-script-incorrect-nonce").style.color = "rgb(255, 0, 0)";
     </script>
     <script nonce="correctstylenonce">
-      window.parent.inlineScriptTestResult("allowed", "blocked", "This script has a correct nonce for styles (but not for scripts)");
+      document.getElementById("inline-script-correct-style-nonce").style.color = "rgb(255, 0, 0)";
     </script>
     <script>
-      window.parent.inlineScriptTestResult("allowed", "blocked", "This script has no nonce");
+      document.getElementById("inline-script-no-nonce").style.color = "rgb(255, 0, 0)";
     </script>
 
     <!-- external scripts -->
     <script nonce="correctscriptnonce" src="http://example.org/tests/content/base/test/csp/file_CSP.sjs?testid=external_script_correct_nonce_good&type=text/javascript"></script>
     <script nonce="anothercorrectscriptnonce" src="http://example.org/tests/content/base/test/csp/file_CSP.sjs?testid=external_script_another_correct_nonce_good&type=text/javascript"></script>
     <script nonce="incorrectscriptnonce" src="http://example.org/tests/content/base/test/csp/file_CSP.sjs?testid=external_script_incorrect_nonce_bad&type=text/javascript"></script>
     <script nonce="correctstylenonce" src="http://example.org/tests/content/base/test/csp/file_CSP.sjs?testid=external_script_correct_style_nonce_bad&type=text/javascript"></script>
     <script src="http://example.org/tests/content/base/test/csp/file_CSP.sjs?testid=external_script_no_nonce_bad&type=text/javascript"></script>
--- a/content/base/test/csp/test_nonce_source.html
+++ b/content/base/test/csp/test_nonce_source.html
@@ -11,24 +11,16 @@
 <div id="content" style="visibility:hidden">
   <iframe style="width:100%;" id='cspframe'></iframe>
 </div>
 <script class="testbody" type="text/javascript">
 
 var testsRun = 0;
 var totalTests = 20;
 
-var inlineScriptTestsRun = 0;
-var totalInlineScriptTests = 4;
-
-var scriptNonceViolations = 0;
-var expectedScriptNonceViolations = 2;
-var scriptInlineViolations = 0;
-var expectedScriptInlineViolations = 1;
-
 // This is used to watch the blocked data bounce off CSP
 function examiner() {
   SpecialPowers.addObserver(this, "specialpowers-http-notify-request", false);
   SpecialPowers.addObserver(this, "csp-on-violate-policy", false);
 }
 
 examiner.prototype = {
   observe: function(subject, topic, data) {
@@ -36,111 +28,100 @@ examiner.prototype = {
 
     //_good things better be allowed!
     //_bad things better be blocked!
 
     if (topic === "specialpowers-http-notify-request") {
       var uri = data;
       if (!testid_re.test(uri)) return;
       var testid = testid_re.exec(uri)[1];
-      ok(/_good/.test(testid), "Allowed URI with testid " + testid);
+      ok(/_good/.test(testid), "should allow URI with good testid " + testid);
       ranTests(1);
     }
 
     if (topic === "csp-on-violate-policy") {
       try {
         // if it is an blocked external load, subject will be the URI of the resource
         var blocked_uri = SpecialPowers.getPrivilegedProps(SpecialPowers.do_QueryInterface(subject, "nsIURI"), "asciiSpec");
         if (!testid_re.test(blocked_uri)) return;
         var testid = testid_re.exec(blocked_uri)[1];
-        ok(/_bad/.test(testid), "Blocked URI with testid " + testid);
+        ok(/_bad/.test(testid), "should block URI with bad testid " + testid);
         ranTests(1);
       } catch (e) {
-        // if the subject is blocked inline, data will be a violation msg (defined at the top of contentSecurityPolicy.js)
-        //dump("** exception in csp-on-violate-policy: " + e + "\n");
-        var violation_msg = SpecialPowers.getPrivilegedProps(SpecialPowers.do_QueryInterface(subject, "nsISupportsCString"), "data");
-        if (/Inline Script/.test(violation_msg)) {
-          if (/Inline Script had invalid nonce/.test(violation_msg))
-            scriptNonceViolations++;
-          if (/Inline Scripts will not execute/.test(violation_msg))
-            scriptInlineViolations++;
-          window.inlineScriptTestResult("blocked", "blocked",
-                                        "Blocked because " + violation_msg);
-        }
+        // if the subject is blocked inline, data will be a violation message
+        // we can't distinguish which resources triggered these, so we ignore them
       }
     }
   },
   // must eventually call this to remove the listener, or mochitests might get borked.
   remove: function() {
     SpecialPowers.removeObserver(this, "specialpowers-http-notify-request");
     SpecialPowers.removeObserver(this, "csp-on-violate-policy");
   }
 }
 
-var inlineScriptTestResult = function(testIs, testShouldBe, description) {
-  if (testIs !== testShouldBe) {
-    ok(false, description);
-  } else {
-    ok(true, description);
-  }
-  ranTests(1)
-
-  inlineScriptTestsRun++;
-  if (inlineScriptTestsRun == totalInlineScriptTests) {
-    if (scriptNonceViolations != expectedScriptNonceViolations)
-      ok(false, "The number of reported script nonce violations does not match expected; got " + scriptNonceViolations + ", expected " + expectedScriptNonceViolations);
-    if (scriptInlineViolations != expectedScriptInlineViolations)
-      ok(false, "The number of reported inline script  violations does not match expected; got " + scriptInlineViolations + ", expected " + expectedScriptInlineViolations);
-    ranTests(2);
-  }
-}
-
 function cleanup() {
   // remove the observer so we don't bork other tests
   window.examiner.remove();
   // finish the tests
   SimpleTest.finish();
 }
 
 function ranTests(num) {
   testsRun += num;
   if (testsRun < totalTests) {
     return;
   }
   cleanup();
 }
 
-function checkStyles () {
+function checkInlineScriptsAndStyles () {
   var cspframe = document.getElementById('cspframe');
   var getElementColorById = function (id) {
     return window.getComputedStyle(cspframe.contentDocument.getElementById(id), null).color;
   };
   // Inline style tries to change an element's color to green. If blocked, the
-  // element's color will be the default black.
+  // element's color will be the (unchanged) default black.
   var green = "rgb(0, 128, 0)";
+  var red = "rgb(255,0,0)";
   var black = "rgb(0, 0, 0)";
 
-  is(getElementColorById('inline-style-correct-nonce'), green, "Inline style with correct nonce allowed");
-  is(getElementColorById('inline-style-incorrect-nonce'), black, "Inline style with incorrect nonce blocked");
-  is(getElementColorById('inline-style-correct-script-nonce'), black, "Inline style with correct nonce for scripts (but incorrect nonce for styles) blocked");
-  is(getElementColorById('inline-style-no-nonce'), black, "Inline style with no nonce blocked");
+  // inline script tests
+  is(getElementColorById('inline-script-correct-nonce'), green,
+     "Inline script with correct nonce should execute");
+  is(getElementColorById('inline-script-incorrect-nonce'), black,
+     "Inline script with incorrect nonce should not execute");
+  is(getElementColorById('inline-script-correct-style-nonce'), black,
+     "Inline script with correct nonce for styles (but not for scripts) should not execute");
+  is(getElementColorById('inline-script-no-nonce'), black,
+     "Inline script with no nonce should not execute");
 
-  ranTests(4);
+  // inline style tests
+  is(getElementColorById('inline-style-correct-nonce'), green,
+     "Inline style with correct nonce should be allowed");
+  is(getElementColorById('inline-style-incorrect-nonce'), black,
+     "Inline style with incorrect nonce should be blocked");
+  is(getElementColorById('inline-style-correct-script-nonce'), black,
+     "Inline style with correct nonce for scripts (but incorrect nonce for styles) should be blocked");
+  is(getElementColorById('inline-style-no-nonce'), black,
+     "Inline style with no nonce should be blocked");
+
+  ranTests(8);
 }
 
 //////////////////////////////////////////////////////////////////////
 // set up and go
 window.examiner = new examiner();
 SimpleTest.waitForExplicitFinish();
 
 SpecialPowers.pushPrefEnv(
   {'set':[["security.csp.speccompliant", true],
           ["security.csp.experimentalEnabled", true]]},
   function() {
     // save this for last so that our listeners are registered.
     // ... this loads the testbed of good and bad requests.
     document.getElementById('cspframe').src = 'file_nonce_source.html';
-    document.getElementById('cspframe').addEventListener('load', checkStyles, false);
+    document.getElementById('cspframe').addEventListener('load', checkInlineScriptsAndStyles, false);
   });
 </script>
 </pre>
 </body>
 </html>