[tor-commits] [tor-browser/tor-browser-38.4.0esr-5.5-1] Regression tests for Bug 15564: Isolate SharedWorker by first party domain

gk at torproject.org gk at torproject.org
Sat Dec 12 20:54:36 UTC 2015


commit 2c8a18f3f6ccd1a1db86b74b7bfca715890c1ed4
Author: Arthur Edelstein <arthuredelstein at gmail.com>
Date:   Thu Oct 8 16:13:59 2015 -0700

    Regression tests for Bug 15564: Isolate SharedWorker by first party domain
---
 dom/base/test/bug15564_child_page.html |   29 ++++++++
 dom/base/test/bug15564_sharedworker.js |    7 ++
 dom/base/test/mochitest.ini            |    3 +
 dom/base/test/test_tor_bug15564.html   |  120 ++++++++++++++++++++++++++++++++
 4 files changed, 159 insertions(+)

diff --git a/dom/base/test/bug15564_child_page.html b/dom/base/test/bug15564_child_page.html
new file mode 100644
index 0000000..e84024e
--- /dev/null
+++ b/dom/base/test/bug15564_child_page.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugs.torproject.org/15564
+-->
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=utf-8">
+  <title>Page SharedWorker creator for Tor Browser Bug 15564</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="text/javascript;version=1.7" src="bug15502_utils.js"></script>
+</head>
+<body>
+<div id="display" style="white-space:pre; font-family:monospace; display:inline;"></div>
+
+<script type="text/javascript;version=1.7">
+
+spawnTask(function* () {
+  sendMessage(window.parent, "ready");
+  let message = yield receiveMessage(window.parent),
+      worker = new SharedWorker("bug15564_sharedworker.js", message);
+  worker.port.onmessage = function (e) {
+    document.getElementById("display").innerHTML = e.data;
+    sendMessage(window.parent, e.data);
+  }
+});
+
+</script>
+</body>
+</html>
diff --git a/dom/base/test/bug15564_sharedworker.js b/dom/base/test/bug15564_sharedworker.js
new file mode 100644
index 0000000..56cbc2c
--- /dev/null
+++ b/dom/base/test/bug15564_sharedworker.js
@@ -0,0 +1,7 @@
+self.randomValue = Math.random();
+
+onconnect = function (e) {
+  var port = e.ports[0];
+  port.postMessage(self.randomValue);
+  port.start();
+};
diff --git a/dom/base/test/mochitest.ini b/dom/base/test/mochitest.ini
index 6a8c334..e8812fb 100644
--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -33,6 +33,8 @@ support-files =
   bug15502_worker_deblobify.html
   bug15703_page_create.html
   bug15703_page_retrieve.html
+  bug15564_child_page.html
+  bug15564_sharedworker.js
   bug282547.sjs
   bug298064-subframe.html
   bug313646.txt
@@ -738,6 +740,7 @@ skip-if = toolkit == 'android' || e10s #RANDOM
 [test_textnode_split_in_selection.html]
 [test_title.html]
 [test_tor_bug15502.html]
+[test_tor_bug15564.html]
 [test_tor_bug15703.html]
 [test_tor_bug17207.html]
 [test_treewalker_nextsibling.xml]
diff --git a/dom/base/test/test_tor_bug15564.html b/dom/base/test/test_tor_bug15564.html
new file mode 100644
index 0000000..3609616
--- /dev/null
+++ b/dom/base/test/test_tor_bug15564.html
@@ -0,0 +1,120 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugs.torproject.org/15564
+-->
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=utf-8">
+  <title>Test for Tor Browser Bug 15564</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="text/javascript;version=1.7" src="bug15502_utils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<p id="display"></p>
+<div id="content"></div>
+
+<script class="testbody" type="application/javascript;version=1.7">
+SimpleTest.waitForExplicitFinish();
+
+// __setPref(key, value)__.
+// Set a pref value asynchronously, returning a promise that resolves
+// when it succeeds.
+let setPref = function* (key, value) {
+  return new Promise(function(resolve, reject) {
+    SpecialPowers.pushPrefEnv({"set": [[key, value]]}, resolve);
+  });
+};
+
+// ## Testing constants
+let domain1 = "http://example.com",
+    domain2 = "http://example.net",
+    path = "/tests/dom/base/test/",
+    child_page = "bug15564_child_page.html";
+
+// __tabIO(domain, child, input)__.
+// Open a parent page at the given `domain`, in a new tab. The
+// parent page should then open a `child` iframe. Post an
+// `input` message to the child. Returns [tab, response].
+let tabIO = function* (domain, child, input) {
+  // Open a new tab with a parent page at the given (first party) domain.
+  tab = window.open(domain + path + "bug15502_tab.html", "_blank");
+  // Wait for the parent page to report that it has completed loading.
+  yield receiveMessage(tab); // ready message
+  // Send a message to the parent page, with a URL for the child page.
+  // The first-party page will load the child page in an iframe.
+  // (Note that every child page always has the same origin, example.org,
+  // but its first-party domain is inherited from the parent page.)
+  sendMessage(tab, "http://example.org" + path + child);
+  // Wait for the child page to report that it has finished loading,
+  // in a message forwarded by the parent page.
+  yield receiveMessage(tab); // ready message
+  // Send the input message to the tab's parent page, which will forward
+  // the message to the child page.
+  sendMessage(tab, input);
+  // The child page will attempt to read a secret random number via a
+  // SharedWorker. If it is unable to find such a number, it
+  // generates a new random number, posts it to the SharedWorker,
+  // and also posts it back to us.
+  // Wait for a message containing the number from the child page,
+  // forwarded by the parent page. Return the tab and the response.
+  return [tab, yield receiveMessage(tab)];
+};
+
+// __sharedWorkerTest(isolationOn, domainA, domainB, childPage)__.
+// Run a test where we set the pref "privacy.thirdparty.isolate" to on or off,
+// and then create a shared worker under first party `domainA`, using the page `child_page`,
+// and then a matching SharedWorker under first party `domainB`, and see if they match.
+let sharedWorkerTest = function* (isolationOn, domainA, domainB, child_page) {
+  // Set the pref to reflect whether we want isolation on or off.
+  // 2 means always on; 0 means always off.
+  yield setPref("privacy.thirdparty.isolate", isolationOn ? 2 : 0);
+  // Open two tabs with parent pages embedding child iframes. The parent (first party)
+  // domains are set to domainA and domainB (which may be the same or different).
+  // The child page always has origin example.org, but gets its first party domain
+  // from the parent page. Report results: are child pages able to share information?
+  let input = isolationOn + "|" + domainA + "|" + domainB,
+      [tabA, firstResult] = yield tabIO(domainA, child_page, input),
+      [tabB, secondResult] = yield tabIO(domainB, child_page, input),
+      description = domainA + ":" + child_page + "->" +
+                    domainB + ":" + child_page +
+                    ", isolation " + (isolationOn ? "on." : "off.");
+  // If the child pages both report the same random number, then they have shared
+  // that number via a SharedWorker. Otherwise sharing was denied.
+  if (isolationOn && domainA !== domainB) {
+    // The isolation pref is enabled and first party domains of the two child pages
+    // are different, so sharing should have been prevented.
+    ok(firstResult !== secondResult, description + " Deny sharing SharedWorker");
+  } else {
+    // The isolation pref is disable, or the first party domain is the same for
+    // both child pages, so the secret data should have been shared.
+    ok(firstResult === secondResult, description + " Allow sharing SharedWorker");
+  }
+  // Clean up tabs now that this test has finished.
+  tabA.close();
+  tabB.close();
+};
+
+// ## The main test
+// Run a coroutine that tests various combinations of domains
+// methods, and isolation states for sharing (or not sharing) SharedWorkers.
+spawnTask(function* () {
+  let domainA = domain1;
+  for (let isolate of [false, true]) {
+    for (let domainB of [domain1, domain2]) {
+       // For the given isolation state, and a pair of first party domains
+       // (which may or not be different), test if secret data can be
+       // shared via a SharedWorker, and if that matches the intended behavior.
+       // Here domainA is always domain1, and domainB is either
+       // domain1 or domain2.
+       yield sharedWorkerTest(isolate, domainA, domainB, child_page);
+    }
+  }
+  SimpleTest.finish();
+});
+
+</script>
+
+</body>
+</html>





More information about the tor-commits mailing list