diff --git a/dom/broadcastchannel/BroadcastChannel.cpp b/dom/broadcastchannel/BroadcastChannel.cpp index de815138b66b..1ee4e0bc8141 100644 --- a/dom/broadcastchannel/BroadcastChannel.cpp +++ b/dom/broadcastchannel/BroadcastChannel.cpp @@ -17,6 +17,7 @@ #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" @@ -299,12 +300,25 @@ BroadcastChannel::Constructor(const GlobalObject& aGlobal, 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 workerRef = StrongWorkerRef::Create(workerPrivate, "BroadcastChannel", [bc] () { bc->Shutdown(); }); diff --git a/modules/libpref/init/StaticPrefList.h b/modules/libpref/init/StaticPrefList.h index 815a8a0c53a8..1c9d5743010e 100644 --- a/modules/libpref/init/StaticPrefList.h +++ b/modules/libpref/init/StaticPrefList.h @@ -1050,7 +1050,7 @@ VARCACHE_PREF( VARCACHE_PREF( "privacy.trackingprotection.storagerestriction.enabled", privacy_trackingprotection_storagerestriction_enabled, - bool, false + RelaxedAtomicBool, false ) //--------------------------------------------------------------------------- diff --git a/toolkit/components/antitracking/test/browser/browser.ini b/toolkit/components/antitracking/test/browser/browser.ini index f644ba057a5a..13ee999993c0 100644 --- a/toolkit/components/antitracking/test/browser/browser.ini +++ b/toolkit/components/antitracking/test/browser/browser.ini @@ -5,3 +5,4 @@ support-files = 3rdParty.html [browser_blockingResources.js] +[browser_blockingMessaging.js] diff --git a/toolkit/components/antitracking/test/browser/browser_blockingMessaging.js b/toolkit/components/antitracking/test/browser/browser_blockingMessaging.js new file mode 100644 index 000000000000..eb7e44b648a5 --- /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(); + }; + }); + });