Bug 1461921 - Block storage access for third-parties on the tracking protection list - part 3 - BroadcastChannel, r=ehsan
authorAndrea Marchesini <amarchesini@mozilla.com>
Wed, 20 Jun 2018 13:38:22 -0400
changeset 423170 c9c37c6ca4373aa7f6ac637a849674e503ae30e5
parent 423169 ba91bc6240f338d749e90e0680a7a84460295f33
child 423171 c34c37fe5f9dacb1c0be20542823597c1e8f32a1
push id34164
push usercsabou@mozilla.com
push dateThu, 21 Jun 2018 01:17:13 +0000
treeherdermozilla-central@d231a3231680 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs1461921
milestone62.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 1461921 - Block storage access for third-parties on the tracking protection list - part 3 - BroadcastChannel, r=ehsan
dom/broadcastchannel/BroadcastChannel.cpp
modules/libpref/init/StaticPrefList.h
toolkit/components/antitracking/test/browser/browser.ini
toolkit/components/antitracking/test/browser/browser_blockingMessaging.js
--- a/dom/broadcastchannel/BroadcastChannel.cpp
+++ b/dom/broadcastchannel/BroadcastChannel.cpp
@@ -12,16 +12,17 @@
 #include "mozilla/dom/StructuredCloneHolder.h"
 #include "mozilla/dom/ipc/StructuredCloneData.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/dom/WorkerRef.h"
 #include "mozilla/dom/WorkerRunnable.h"
 #include "mozilla/ipc/BackgroundChild.h"
 #include "mozilla/ipc/BackgroundUtils.h"
 #include "mozilla/ipc/PBackgroundChild.h"
+#include "mozilla/StaticPrefs.h"
 #include "nsContentUtils.h"
 
 #include "nsIBFCacheEntry.h"
 #include "nsIDocument.h"
 #include "nsISupportsPrimitives.h"
 
 #ifdef XP_WIN
 #undef PostMessage
@@ -294,22 +295,35 @@ BroadcastChannel::Constructor(const Glob
     if (NS_WARN_IF(aRv.Failed())) {
       return nullptr;
     }
 
     aRv = PrincipalToPrincipalInfo(principal, &principalInfo);
     if (NS_WARN_IF(aRv.Failed())) {
       return nullptr;
     }
+
+    if (StaticPrefs::privacy_trackingprotection_storagerestriction_enabled() &&
+        nsContentUtils::StorageAllowedForWindow(window) !=
+          nsContentUtils::StorageAccess::eAllow) {
+      aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
+      return nullptr;
+    }
   } else {
     JSContext* cx = aGlobal.Context();
 
     WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
     MOZ_ASSERT(workerPrivate);
 
+    if (StaticPrefs::privacy_trackingprotection_storagerestriction_enabled() &&
+        !workerPrivate->IsStorageAllowed()) {
+      aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
+      return nullptr;
+    }
+
     RefPtr<StrongWorkerRef> workerRef =
       StrongWorkerRef::Create(workerPrivate, "BroadcastChannel",
                               [bc] () { bc->Shutdown(); });
     // We are already shutting down the worker. Let's return a non-active
     // object.
     if (NS_WARN_IF(!workerRef)) {
       aRv.Throw(NS_ERROR_FAILURE);
       return nullptr;
--- a/modules/libpref/init/StaticPrefList.h
+++ b/modules/libpref/init/StaticPrefList.h
@@ -1045,16 +1045,16 @@ VARCACHE_PREF(
 
 //---------------------------------------------------------------------------
 // Anti-Tracking prefs
 //---------------------------------------------------------------------------
 
 VARCACHE_PREF(
   "privacy.trackingprotection.storagerestriction.enabled",
    privacy_trackingprotection_storagerestriction_enabled,
-  bool, false
+  RelaxedAtomicBool, false
 )
 
 //---------------------------------------------------------------------------
 // End of prefs
 //---------------------------------------------------------------------------
 
 // clang-format on
--- a/toolkit/components/antitracking/test/browser/browser.ini
+++ b/toolkit/components/antitracking/test/browser/browser.ini
@@ -1,7 +1,8 @@
 [DEFAULT]
 support-files =
   head.js
   page.html
   3rdParty.html
 
 [browser_blockingResources.js]
+[browser_blockingMessaging.js]
new file mode 100644
--- /dev/null
+++ b/toolkit/components/antitracking/test/browser/browser_blockingMessaging.js
@@ -0,0 +1,62 @@
+AntiTracking.runTest("BroadcastChannel",
+  async _ => {
+    try {
+      new BroadcastChannel("hello");
+      ok(false, "BroadcastChannel cannot be used!");
+    } catch (e) {
+      ok(true, "BroadcastChannel cannot be used!");
+      is(e.name, "SecurityError", "We want a security error message.");
+    }
+  },
+  async _ => {
+    new BroadcastChannel("hello");
+    ok(true, "BroadcastChannel can be used");
+  });
+
+AntiTracking.runTest("BroadcastChannel in workers",
+  async _ => {
+    function blockingCode() {
+      try {
+        new BroadcastChannel("hello");
+        postMessage(false);
+      } catch (e) {
+        postMessage(e.name == "SecurityError");
+      }
+    }
+
+    let blob = new Blob([blockingCode.toString() + "; blockingCode();"]);
+    ok(blob, "Blob has been created");
+
+    let blobURL = URL.createObjectURL(blob);
+    ok(blobURL, "Blob URL has been created");
+
+    let worker = new Worker(blobURL);
+    ok(worker, "Worker has been created");
+
+    await new Promise(resolve => {
+      worker.onmessage = function(e) {
+        resolve();
+      };
+    });
+  },
+  async _ => {
+    function nonBlockingCode() {
+      new BroadcastChannel("hello");
+      postMessage(true);
+    }
+
+    let blob = new Blob([nonBlockingCode.toString() + "; nonBlockingCode();"]);
+    ok(blob, "Blob has been created");
+
+    let blobURL = URL.createObjectURL(blob);
+    ok(blobURL, "Blob URL has been created");
+
+    let worker = new Worker(blobURL);
+    ok(worker, "Worker has been created");
+
+    await new Promise(resolve => {
+      worker.onmessage = function(e) {
+        resolve();
+      };
+    });
+  });