[tbb-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 tbb-commits
mailing list