Bug 911547 - Test CSP enforcement in session-restored documents. r=ttaubert, a=lsblakk
authorSid Stamm <sstamm@mozilla.com>
Thu, 23 Jan 2014 15:34:56 -0800
changeset 176091 566fa92f4b79e787c21a3ef277ba033f4424f422
parent 176090 947bebfbe77834df5f554b8b6b249c9a7ea6ffca
child 176092 82bc631a9e53a14d8abf4e40d4db7508d6e7e279
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersttaubert, lsblakk
bugs911547
milestone28.0a2
Bug 911547 - Test CSP enforcement in session-restored documents. r=ttaubert, a=lsblakk
browser/components/sessionstore/test/browser.ini
browser/components/sessionstore/test/browser_911547.js
browser/components/sessionstore/test/browser_911547_sample.html
browser/components/sessionstore/test/browser_911547_sample.html^headers^
--- a/browser/components/sessionstore/test/browser.ini
+++ b/browser/components/sessionstore/test/browser.ini
@@ -32,16 +32,18 @@ support-files =
   browser_597315_a.html
   browser_597315_b.html
   browser_597315_c.html
   browser_597315_c1.html
   browser_597315_c2.html
   browser_662743_sample.html
   browser_739531_sample.html
   browser_916390_sample.html
+  browser_911547_sample.html
+  browser_911547_sample.html^headers^
 
 #NB: the following are disabled
 #  browser_464620_a.html
 #  browser_464620_b.html 
 #  browser_464620_xd.html
 
 
 #disabled-for-intermittent-failures--bug-766044, browser_459906_empty.html
@@ -169,8 +171,9 @@ skip-if = true
 skip-if = true
 
 # Disabled on OS X:
 [browser_597071.js]
 skip-if = os == "mac"
 [browser_625016.js]
 skip-if = os == "mac"
 
+[browser_911547.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/test/browser_911547.js
@@ -0,0 +1,70 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// This tests that session restore component does restore the right content
+// security policy with the document.
+// The policy being tested disallows inline scripts
+
+function test() {
+  TestRunner.run();
+}
+
+function runTests() {
+  // create a tab that has a CSP
+  let testURL = "http://mochi.test:8888/browser/browser/components/sessionstore/test/browser_911547_sample.html";
+  let tab = gBrowser.selectedTab = gBrowser.addTab(testURL);
+  gBrowser.selectedTab = tab;
+
+  let browser = tab.linkedBrowser;
+  yield waitForLoad(browser);
+
+  // this is a baseline to ensure CSP is active
+  // attempt to inject and run a script via inline (pre-restore, allowed)
+  injectInlineScript(browser,'document.getElementById("test_id").value = "fail";');
+  is(browser.contentDocument.getElementById("test_id").value, "ok",
+     "CSP should block the inline script that modifies test_id");
+
+  // attempt to click a link to a data: URI (will inherit the CSP of the
+  // origin document) and navigate to the data URI in the link.
+  browser.contentDocument.getElementById("test_data_link").click();
+  yield waitForLoad(browser);
+
+  is(browser.contentDocument.getElementById("test_id2").value, "ok",
+     "CSP should block the script loaded by the clicked data URI");
+
+  // close the tab
+  gBrowser.removeTab(tab);
+
+  // open new tab and recover the state
+  tab = ss.undoCloseTab(window, 0);
+  yield waitForTabRestored(tab);
+  browser = tab.linkedBrowser;
+
+  is(browser.contentDocument.getElementById("test_id2").value, "ok",
+     "CSP should block the script loaded by the clicked data URI after restore");
+
+  // clean up
+  gBrowser.removeTab(tab);
+}
+
+function waitForLoad(aElement) {
+  aElement.addEventListener("load", function onLoad() {
+    aElement.removeEventListener("load", onLoad, true);
+    executeSoon(next);
+  }, true);
+}
+
+function waitForTabRestored(aElement) {
+  aElement.addEventListener("SSTabRestored", function tabRestored(e) {
+    aElement.removeEventListener("SSTabRestored", tabRestored, true);
+    executeSoon(next);
+  }, true);
+}
+
+// injects an inline script element (with a text body)
+function injectInlineScript(browser, scriptText) {
+  let scriptElt = browser.contentDocument.createElement("script");
+  scriptElt.type = 'text/javascript';
+  scriptElt.text = scriptText;
+  browser.contentDocument.body.appendChild(scriptElt);
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/test/browser_911547_sample.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Test 911547</title>
+  </head>
+<body>
+
+  <!--
+   this element gets modified by an injected script;
+   that script should be blocked by CSP.
+   Inline scripts can modify it, but not data uris.
+  -->
+  <input type="text" id="test_id" value="ok">
+
+  <a id="test_data_link" href="data:text/html,<input type='text' id='test_id2' value='ok'/> <script>document.getElementById('test_id2').value = 'fail';</script>">Test Link</a>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/test/browser_911547_sample.html^headers^
@@ -0,0 +1,1 @@
+Content-Security-Policy: script-src 'self'