diff --git a/dom/base/nsGlobalWindowInner.cpp b/dom/base/nsGlobalWindowInner.cpp index 67cb41d19dab..b6fe6a09eb41 100644 --- a/dom/base/nsGlobalWindowInner.cpp +++ b/dom/base/nsGlobalWindowInner.cpp @@ -3253,6 +3253,14 @@ bool nsGlobalWindowInner::CachesEnabled(JSContext* aCx, JSObject*) { if (!StaticPrefs::dom_caches_enabled()) { return false; } + if (StaticPrefs::dom_caches_hide_in_pbmode_enabled()) { + if (const nsCOMPtr global = + xpc::CurrentNativeGlobal(aCx)) { + if (global->GetStorageAccess() == StorageAccess::ePrivateBrowsing) { + return false; + } + } + } if (!JS::GetIsSecureContext(js::GetContextRealm(aCx))) { return StaticPrefs::dom_caches_testing_enabled() || StaticPrefs::dom_serviceWorkers_testing_enabled(); diff --git a/dom/base/test/chrome/chrome.ini b/dom/base/test/chrome/chrome.ini index 2f11aed22f84..da932a0df4fc 100644 --- a/dom/base/test/chrome/chrome.ini +++ b/dom/base/test/chrome/chrome.ini @@ -21,7 +21,7 @@ support-files = window_swapFrameLoaders.xhtml prefs = gfx.font_rendering.fallback.async=false - + [test_bug120684.xhtml] [test_bug206691.xhtml] [test_bug289714.xhtml] @@ -82,3 +82,6 @@ support-files = file_title.xhtml [test_swapFrameLoaders.xhtml] skip-if = os == 'mac' # bug 1674413 [test_bug1339722.html] +[test_hide_in_pbmode.html] +support-files = + file_hide_in_pbmode.js diff --git a/dom/base/test/chrome/file_hide_in_pbmode.js b/dom/base/test/chrome/file_hide_in_pbmode.js new file mode 100644 index 000000000000..a6bf8761232a --- /dev/null +++ b/dom/base/test/chrome/file_hide_in_pbmode.js @@ -0,0 +1,68 @@ +/* global importScripts */ + +const isWorker = typeof DedicatedWorkerGlobalScope === "function"; + +function check(content, expected, item) { + const exposed = expected ? "is exposed without" : "is not exposed with"; + const worker = isWorker ? "in worker" : "in window"; + is( + content.eval(`!!globalThis.${item}`), + expected, + `${item} ${exposed} pbmode ${worker}` + ); +} + +function checkCaches(content, expected) { + check(content, expected, "caches"); + check(content, expected, "Cache"); + check(content, expected, "CacheStorage"); +} + +function checkIDB(content, expected) { + check(content, expected, "indexedDB"); + check(content, expected, "IDBCursor"); + check(content, expected, "IDBDatabase"); + check(content, expected, "IDBFactory"); + check(content, expected, "IDBIndex"); + check(content, expected, "IDBKeyRange"); + check(content, expected, "IDBObjectStore"); + check(content, expected, "IDBOpenDBRequest"); + check(content, expected, "IDBRequest"); + check(content, expected, "IDBTransaction"); + check(content, expected, "IDBVersionChangeEvent"); +} + +function checkSW(content, expected) { + if (isWorker) { + // Currently not supported. Bug 1131324 + return; + } + check(content, expected, "navigator.serviceWorker"); + check(content, expected, "ServiceWorker"); + check(content, expected, "ServiceWorkerContainer"); + check(content, expected, "ServiceWorkerRegistration"); + check(content, expected, "NavigationPreloadManager"); + check(content, expected, "PushManager"); + check(content, expected, "PushSubscription"); + check(content, expected, "PushSubscriptionOptions"); +} + +function checkAll(content, expected) { + checkCaches(content, expected); + checkIDB(content, expected); + checkSW(content, expected); +} + +if (isWorker) { + importScripts("/tests/SimpleTest/WorkerSimpleTest.js"); + + globalThis.onmessage = ev => { + const { expected } = ev.data; + checkAll(globalThis, expected); + postMessage({ + kind: "info", + next: true, + description: "Worker test finished", + }); + }; +} diff --git a/dom/base/test/chrome/test_hide_in_pbmode.html b/dom/base/test/chrome/test_hide_in_pbmode.html new file mode 100644 index 000000000000..263eba105c8e --- /dev/null +++ b/dom/base/test/chrome/test_hide_in_pbmode.html @@ -0,0 +1,70 @@ + +Test for hiding features in Private Browsing + + + + + diff --git a/dom/cache/test/browser/browser.ini b/dom/cache/test/browser/browser.ini index 90a7a53a3a36..05cb6dbd0717 100644 --- a/dom/cache/test/browser/browser.ini +++ b/dom/cache/test/browser/browser.ini @@ -1 +1,5 @@ +[DEFAULT] +prefs = + dom.caches.hide_in_pbmode.enabled=false + [browser_cache_pb_window.js] diff --git a/dom/indexedDB/IDBFactory.cpp b/dom/indexedDB/IDBFactory.cpp index 29da76b6a264..cf293ec5a115 100644 --- a/dom/indexedDB/IDBFactory.cpp +++ b/dom/indexedDB/IDBFactory.cpp @@ -359,6 +359,21 @@ bool IDBFactory::AllowedForPrincipal(nsIPrincipal* aPrincipal, return !aPrincipal->GetIsNullPrincipal(); } +bool IDBFactory::IsEnabled(JSContext* aCx, JSObject* aGlobal) { + if (StaticPrefs::dom_indexedDB_privateBrowsing_enabled()) { + return true; + } + if (StaticPrefs::dom_indexedDB_hide_in_pbmode_enabled()) { + if (const nsCOMPtr global = + xpc::CurrentNativeGlobal(aCx)) { + if (global->GetStorageAccess() == StorageAccess::ePrivateBrowsing) { + return false; + } + } + } + return true; +} + void IDBFactory::UpdateActiveTransactionCount(int32_t aDelta) { AssertIsOnOwningThread(); MOZ_DIAGNOSTIC_ASSERT(aDelta > 0 || (mActiveTransactionCount + aDelta) < diff --git a/dom/indexedDB/IDBFactory.h b/dom/indexedDB/IDBFactory.h index 75f05fb19cb1..97a0d97859c6 100644 --- a/dom/indexedDB/IDBFactory.h +++ b/dom/indexedDB/IDBFactory.h @@ -97,6 +97,8 @@ class IDBFactory final : public nsISupports, public nsWrapperCache { static bool AllowedForPrincipal(nsIPrincipal* aPrincipal, bool* aIsSystemPrincipal = nullptr); + static bool IsEnabled(JSContext* aCx, JSObject* aGlobal); + void AssertIsOnOwningThread() const { NS_ASSERT_OWNINGTHREAD(IDBFactory); } nsISerialEventTarget* EventTarget() const { diff --git a/dom/indexedDB/test/browser.ini b/dom/indexedDB/test/browser.ini index 351df387b05d..486286fd168d 100644 --- a/dom/indexedDB/test/browser.ini +++ b/dom/indexedDB/test/browser.ini @@ -1,6 +1,7 @@ [DEFAULT] prefs = dom.indexedDB.storageOption.enabled=true + dom.indexedDB.hide_in_pbmode.enabled=false skip-if = (buildapp != "browser") support-files = head.js diff --git a/dom/serviceworkers/ServiceWorker.cpp b/dom/serviceworkers/ServiceWorker.cpp index 47e64cf3c8ad..f10674598a21 100644 --- a/dom/serviceworkers/ServiceWorker.cpp +++ b/dom/serviceworkers/ServiceWorker.cpp @@ -53,9 +53,12 @@ bool ServiceWorkersEnabled(JSContext* aCx, JSObject* aGlobal) { // xpc::CurrentNativeGlobal below requires rooting JS::Rooted global(aCx, aGlobal); - if (const nsCOMPtr global = xpc::CurrentNativeGlobal(aCx)) { - if (global->GetStorageAccess() == StorageAccess::ePrivateBrowsing) { - return false; + if (StaticPrefs::dom_serviceWorkers_hide_in_pbmode_enabled()) { + if (const nsCOMPtr global = + xpc::CurrentNativeGlobal(aCx)) { + if (global->GetStorageAccess() == StorageAccess::ePrivateBrowsing) { + return false; + } } } diff --git a/dom/webidl/IDBCursor.webidl b/dom/webidl/IDBCursor.webidl index 0784ac144022..988148b5b4d9 100644 --- a/dom/webidl/IDBCursor.webidl +++ b/dom/webidl/IDBCursor.webidl @@ -14,7 +14,7 @@ enum IDBCursorDirection { "prevunique" }; -[Exposed=(Window,Worker)] +[Exposed=(Window,Worker), Func="IDBFactory::IsEnabled"] interface IDBCursor { readonly attribute (IDBObjectStore or IDBIndex) source; @@ -45,7 +45,7 @@ interface IDBCursor { IDBRequest delete (); }; -[Exposed=(Window,Worker)] +[Exposed=(Window,Worker), Func="IDBFactory::IsEnabled"] interface IDBCursorWithValue : IDBCursor { [Throws] readonly attribute any value; diff --git a/dom/webidl/IDBDatabase.webidl b/dom/webidl/IDBDatabase.webidl index a35281eb1f66..0f28886f8f92 100644 --- a/dom/webidl/IDBDatabase.webidl +++ b/dom/webidl/IDBDatabase.webidl @@ -10,7 +10,7 @@ * liability, trademark and document use rules apply. */ -[Exposed=(Window,Worker)] +[Exposed=(Window,Worker), Func="IDBFactory::IsEnabled"] interface IDBDatabase : EventTarget { readonly attribute DOMString name; readonly attribute unsigned long long version; diff --git a/dom/webidl/IDBFactory.webidl b/dom/webidl/IDBFactory.webidl index 57826b231728..9434a7e12c95 100644 --- a/dom/webidl/IDBFactory.webidl +++ b/dom/webidl/IDBFactory.webidl @@ -23,7 +23,7 @@ dictionary IDBOpenDBOptions * http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBFactory * for more information. */ -[Exposed=(Window,Worker)] +[Exposed=(Window,Worker), Func="IDBFactory::IsEnabled"] interface IDBFactory { [Throws, NeedsCallerType] IDBOpenDBRequest diff --git a/dom/webidl/IDBIndex.webidl b/dom/webidl/IDBIndex.webidl index ff2f215d8381..54d9b5d178c3 100644 --- a/dom/webidl/IDBIndex.webidl +++ b/dom/webidl/IDBIndex.webidl @@ -18,7 +18,7 @@ dictionary IDBIndexParameters { DOMString? locale = null; }; -[Exposed=(Window,Worker)] +[Exposed=(Window,Worker), Func="IDBFactory::IsEnabled"] interface IDBIndex { [SetterThrows] attribute DOMString name; diff --git a/dom/webidl/IDBKeyRange.webidl b/dom/webidl/IDBKeyRange.webidl index 92469aeb049a..d36dd854b0d3 100644 --- a/dom/webidl/IDBKeyRange.webidl +++ b/dom/webidl/IDBKeyRange.webidl @@ -9,7 +9,7 @@ * liability, trademark and document use rules apply. */ -[Exposed=(Window,Worker)] +[Exposed=(Window,Worker), Func="IDBFactory::IsEnabled"] interface IDBKeyRange { [Throws] readonly attribute any lower; diff --git a/dom/webidl/IDBObjectStore.webidl b/dom/webidl/IDBObjectStore.webidl index 105f3501f234..3ae08de871b7 100644 --- a/dom/webidl/IDBObjectStore.webidl +++ b/dom/webidl/IDBObjectStore.webidl @@ -12,7 +12,7 @@ dictionary IDBObjectStoreParameters { boolean autoIncrement = false; }; -[Exposed=(Window,Worker)] +[Exposed=(Window,Worker), Func="IDBFactory::IsEnabled"] interface IDBObjectStore { [SetterThrows] attribute DOMString name; diff --git a/dom/webidl/IDBOpenDBRequest.webidl b/dom/webidl/IDBOpenDBRequest.webidl index 8668009a6b78..48c3add1c560 100644 --- a/dom/webidl/IDBOpenDBRequest.webidl +++ b/dom/webidl/IDBOpenDBRequest.webidl @@ -7,7 +7,7 @@ * https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBOpenDBRequest */ -[Exposed=(Window,Worker)] +[Exposed=(Window,Worker), Func="IDBFactory::IsEnabled"] interface IDBOpenDBRequest : IDBRequest { attribute EventHandler onblocked; diff --git a/dom/webidl/IDBRequest.webidl b/dom/webidl/IDBRequest.webidl index 029368bc7d19..408942dae87f 100644 --- a/dom/webidl/IDBRequest.webidl +++ b/dom/webidl/IDBRequest.webidl @@ -13,7 +13,7 @@ enum IDBRequestReadyState { "done" }; -[Exposed=(Window,Worker)] +[Exposed=(Window,Worker), Func="IDBFactory::IsEnabled"] interface IDBRequest : EventTarget { [Throws] readonly attribute any result; diff --git a/dom/webidl/IDBTransaction.webidl b/dom/webidl/IDBTransaction.webidl index 3b832427b19d..1bfb458d3b55 100644 --- a/dom/webidl/IDBTransaction.webidl +++ b/dom/webidl/IDBTransaction.webidl @@ -19,7 +19,7 @@ enum IDBTransactionMode { "versionchange" }; -[Exposed=(Window,Worker)] +[Exposed=(Window,Worker), Func="IDBFactory::IsEnabled"] interface IDBTransaction : EventTarget { [Throws] readonly attribute IDBTransactionMode mode; diff --git a/dom/webidl/IDBVersionChangeEvent.webidl b/dom/webidl/IDBVersionChangeEvent.webidl index d35030164f16..d331f6966d43 100644 --- a/dom/webidl/IDBVersionChangeEvent.webidl +++ b/dom/webidl/IDBVersionChangeEvent.webidl @@ -15,7 +15,7 @@ dictionary IDBVersionChangeEventInit : EventInit { unsigned long long? newVersion = null; }; -[Exposed=(Window,Worker)] +[Exposed=(Window,Worker), Func="IDBFactory::IsEnabled"] interface IDBVersionChangeEvent : Event { constructor(DOMString type, optional IDBVersionChangeEventInit eventInitDict = {}); diff --git a/dom/webidl/WindowOrWorkerGlobalScope.webidl b/dom/webidl/WindowOrWorkerGlobalScope.webidl index af4f88e7a70b..66be3f7e7619 100644 --- a/dom/webidl/WindowOrWorkerGlobalScope.webidl +++ b/dom/webidl/WindowOrWorkerGlobalScope.webidl @@ -69,9 +69,9 @@ partial interface mixin WindowOrWorkerGlobalScope { // http://w3c.github.io/IndexedDB/#factory-interface partial interface mixin WindowOrWorkerGlobalScope { - // readonly attribute IDBFactory indexedDB; - [Throws] - readonly attribute IDBFactory? indexedDB; + // readonly attribute IDBFactory indexedDB; // bug 1776789 + [Throws, Func="IDBFactory::IsEnabled"] + readonly attribute IDBFactory? indexedDB; }; // https://w3c.github.io/ServiceWorker/#self-caches diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index b292328d43b2..a58cb80a5710 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -2051,6 +2051,12 @@ value: false mirror: always +# Disable CacheStorage in private browsing mode. +- name: dom.caches.hide_in_pbmode.enabled + type: RelaxedAtomicBool + value: @IS_NIGHTLY_BUILD@ + mirror: always + # Disable capture attribute for input elements; only supported on GeckoView. - name: dom.capture.enabled type: bool @@ -2534,12 +2540,18 @@ value: false mirror: always -# Enable indexedDB in private browsing mode. +# Enable indexedDB in private browsing mode with encryption - name: dom.indexedDB.privateBrowsing.enabled type: RelaxedAtomicBool value: false mirror: always +# Disable IndexedDB in private browsing mode. +- name: dom.indexedDB.hide_in_pbmode.enabled + type: RelaxedAtomicBool + value: @IS_NIGHTLY_BUILD@ + mirror: always + - name: dom.input_events.beforeinput.enabled type: bool value: true @@ -3594,6 +3606,12 @@ value: false mirror: always +# Disable ServiceWorker in private browsing mode. +- name: dom.serviceWorkers.hide_in_pbmode.enabled + type: RelaxedAtomicBool + value: true + mirror: always + - name: dom.workers.requestAnimationFrame type: RelaxedAtomicBool value: true diff --git a/toolkit/components/antitracking/test/browser/browser_blockingIndexedDb.js b/toolkit/components/antitracking/test/browser/browser_blockingIndexedDb.js index c386612df1a6..6cfcee89b4d1 100644 --- a/toolkit/components/antitracking/test/browser/browser_blockingIndexedDb.js +++ b/toolkit/components/antitracking/test/browser/browser_blockingIndexedDb.js @@ -26,7 +26,8 @@ AntiTracking.runTestInNormalAndPrivateMode( resolve() ); }); - } + }, + [["dom.indexedDB.hide_in_pbmode.enabled", false]] ); AntiTracking.runTestInNormalAndPrivateMode( @@ -97,7 +98,7 @@ AntiTracking.runTestInNormalAndPrivateMode( ); }); }, - null, + [["dom.indexedDB.hide_in_pbmode.enabled", false]], false, false ); diff --git a/toolkit/components/antitracking/test/browser/browser_blockingIndexedDbInWorkers.js b/toolkit/components/antitracking/test/browser/browser_blockingIndexedDbInWorkers.js index c9ae0d165417..97deb6adf889 100644 --- a/toolkit/components/antitracking/test/browser/browser_blockingIndexedDbInWorkers.js +++ b/toolkit/components/antitracking/test/browser/browser_blockingIndexedDbInWorkers.js @@ -70,5 +70,6 @@ AntiTracking.runTestInNormalAndPrivateMode( resolve() ); }); - } + }, + [["dom.indexedDB.hide_in_pbmode.enabled", false]] ); diff --git a/toolkit/components/antitracking/test/browser/browser_blockingIndexedDbInWorkers2.js b/toolkit/components/antitracking/test/browser/browser_blockingIndexedDbInWorkers2.js index fb7f3d2c67ab..4d23cec7191d 100644 --- a/toolkit/components/antitracking/test/browser/browser_blockingIndexedDbInWorkers2.js +++ b/toolkit/components/antitracking/test/browser/browser_blockingIndexedDbInWorkers2.js @@ -148,7 +148,7 @@ AntiTracking.runTestInNormalAndPrivateMode( ); }); }, - null, + [["dom.indexedDB.hide_in_pbmode.enabled", false]], false, false );