Bug 1776109 - Part 3: Hide caches/indexedDB/serviceWorker in PBMode r=asuth,twisniewski

Differential Revision: https://phabricator.services.mozilla.com/D150064
This commit is contained in:
Kagami Sascha Rosylight 2022-06-30 01:35:13 +00:00
Родитель e772d23751
Коммит 30b8df0dc0
24 изменённых файлов: 217 добавлений и 23 удалений

Просмотреть файл

@ -3253,6 +3253,14 @@ bool nsGlobalWindowInner::CachesEnabled(JSContext* aCx, JSObject*) {
if (!StaticPrefs::dom_caches_enabled()) { if (!StaticPrefs::dom_caches_enabled()) {
return false; return false;
} }
if (StaticPrefs::dom_caches_hide_in_pbmode_enabled()) {
if (const nsCOMPtr<nsIGlobalObject> global =
xpc::CurrentNativeGlobal(aCx)) {
if (global->GetStorageAccess() == StorageAccess::ePrivateBrowsing) {
return false;
}
}
}
if (!JS::GetIsSecureContext(js::GetContextRealm(aCx))) { if (!JS::GetIsSecureContext(js::GetContextRealm(aCx))) {
return StaticPrefs::dom_caches_testing_enabled() || return StaticPrefs::dom_caches_testing_enabled() ||
StaticPrefs::dom_serviceWorkers_testing_enabled(); StaticPrefs::dom_serviceWorkers_testing_enabled();

Просмотреть файл

@ -21,7 +21,7 @@ support-files =
window_swapFrameLoaders.xhtml window_swapFrameLoaders.xhtml
prefs = prefs =
gfx.font_rendering.fallback.async=false gfx.font_rendering.fallback.async=false
[test_bug120684.xhtml] [test_bug120684.xhtml]
[test_bug206691.xhtml] [test_bug206691.xhtml]
[test_bug289714.xhtml] [test_bug289714.xhtml]
@ -82,3 +82,6 @@ support-files = file_title.xhtml
[test_swapFrameLoaders.xhtml] [test_swapFrameLoaders.xhtml]
skip-if = os == 'mac' # bug 1674413 skip-if = os == 'mac' # bug 1674413
[test_bug1339722.html] [test_bug1339722.html]
[test_hide_in_pbmode.html]
support-files =
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",
});
};
}

Просмотреть файл

@ -0,0 +1,70 @@
<!DOCTYPE html>
<title>Test for hiding features in Private Browsing</title>
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script src="chrome://mochikit/content/tests/SimpleTest/WorkerHandler.js"></script>
<script src="file_hide_in_pbmode.js"></script>
<link rel="stylesheet" href="chrome://mochikit/content/tests/SimpleTest/test.css">
<script>
const { BrowserTestUtils } = ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm");
const contentPage = "https://example.org/chrome/dom/workers/test/empty.html";
function openBrowserWindow(url, { private }) {
return new Promise(resolve => {
const win = window.browsingContext.topChromeWindow.OpenBrowserWindow({ private });
win.addEventListener("load", () => {
const listener = () => {
if (win.content.location.href != contentPage) {
BrowserTestUtils.loadURI(win.gBrowser, contentPage);
return;
}
win.removeEventListener("DOMContentLoaded", listener);
resolve(win);
}
win.addEventListener("DOMContentLoaded", listener);
}, { once: true });
});
}
function runWorkerTest(content, expected) {
return new Promise((resolve, reject) => {
/** @type {Worker} */
const worker = content.eval("new Worker('/chrome/dom/base/test/chrome/file_hide_in_pbmode.js')");
worker.postMessage({ expected });
worker.onerror = reject;
listenForTests(worker);
worker.addEventListener("message", ev => {
if (ev.data.next) {
worker.terminate();
resolve();
}
});
});
}
async function runTest() {
// sanity check
let win = await openBrowserWindow(contentPage, { private: false });
checkAll(win.content, true);
await runWorkerTest(win.content, true);
win.close();
win = await openBrowserWindow(contentPage, { private: true });
checkAll(win.content, false);
await runWorkerTest(win.content, false);
win.close();
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({
set: [
["dom.caches.hide_in_pbmode.enabled", true],
["dom.indexedDB.hide_in_pbmode.enabled", true],
["dom.serviceWorkers.hide_in_pbmode.enabled", true],
]
}, runTest);
</script>

4
dom/cache/test/browser/browser.ini поставляемый
Просмотреть файл

@ -1 +1,5 @@
[DEFAULT]
prefs =
dom.caches.hide_in_pbmode.enabled=false
[browser_cache_pb_window.js] [browser_cache_pb_window.js]

Просмотреть файл

@ -359,6 +359,21 @@ bool IDBFactory::AllowedForPrincipal(nsIPrincipal* aPrincipal,
return !aPrincipal->GetIsNullPrincipal(); 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<nsIGlobalObject> global =
xpc::CurrentNativeGlobal(aCx)) {
if (global->GetStorageAccess() == StorageAccess::ePrivateBrowsing) {
return false;
}
}
}
return true;
}
void IDBFactory::UpdateActiveTransactionCount(int32_t aDelta) { void IDBFactory::UpdateActiveTransactionCount(int32_t aDelta) {
AssertIsOnOwningThread(); AssertIsOnOwningThread();
MOZ_DIAGNOSTIC_ASSERT(aDelta > 0 || (mActiveTransactionCount + aDelta) < MOZ_DIAGNOSTIC_ASSERT(aDelta > 0 || (mActiveTransactionCount + aDelta) <

Просмотреть файл

@ -97,6 +97,8 @@ class IDBFactory final : public nsISupports, public nsWrapperCache {
static bool AllowedForPrincipal(nsIPrincipal* aPrincipal, static bool AllowedForPrincipal(nsIPrincipal* aPrincipal,
bool* aIsSystemPrincipal = nullptr); bool* aIsSystemPrincipal = nullptr);
static bool IsEnabled(JSContext* aCx, JSObject* aGlobal);
void AssertIsOnOwningThread() const { NS_ASSERT_OWNINGTHREAD(IDBFactory); } void AssertIsOnOwningThread() const { NS_ASSERT_OWNINGTHREAD(IDBFactory); }
nsISerialEventTarget* EventTarget() const { nsISerialEventTarget* EventTarget() const {

Просмотреть файл

@ -1,6 +1,7 @@
[DEFAULT] [DEFAULT]
prefs = prefs =
dom.indexedDB.storageOption.enabled=true dom.indexedDB.storageOption.enabled=true
dom.indexedDB.hide_in_pbmode.enabled=false
skip-if = (buildapp != "browser") skip-if = (buildapp != "browser")
support-files = support-files =
head.js head.js

Просмотреть файл

@ -53,9 +53,12 @@ bool ServiceWorkersEnabled(JSContext* aCx, JSObject* aGlobal) {
// xpc::CurrentNativeGlobal below requires rooting // xpc::CurrentNativeGlobal below requires rooting
JS::Rooted<JSObject*> global(aCx, aGlobal); JS::Rooted<JSObject*> global(aCx, aGlobal);
if (const nsCOMPtr<nsIGlobalObject> global = xpc::CurrentNativeGlobal(aCx)) { if (StaticPrefs::dom_serviceWorkers_hide_in_pbmode_enabled()) {
if (global->GetStorageAccess() == StorageAccess::ePrivateBrowsing) { if (const nsCOMPtr<nsIGlobalObject> global =
return false; xpc::CurrentNativeGlobal(aCx)) {
if (global->GetStorageAccess() == StorageAccess::ePrivateBrowsing) {
return false;
}
} }
} }

Просмотреть файл

@ -14,7 +14,7 @@ enum IDBCursorDirection {
"prevunique" "prevunique"
}; };
[Exposed=(Window,Worker)] [Exposed=(Window,Worker), Func="IDBFactory::IsEnabled"]
interface IDBCursor { interface IDBCursor {
readonly attribute (IDBObjectStore or IDBIndex) source; readonly attribute (IDBObjectStore or IDBIndex) source;
@ -45,7 +45,7 @@ interface IDBCursor {
IDBRequest delete (); IDBRequest delete ();
}; };
[Exposed=(Window,Worker)] [Exposed=(Window,Worker), Func="IDBFactory::IsEnabled"]
interface IDBCursorWithValue : IDBCursor { interface IDBCursorWithValue : IDBCursor {
[Throws] [Throws]
readonly attribute any value; readonly attribute any value;

Просмотреть файл

@ -10,7 +10,7 @@
* liability, trademark and document use rules apply. * liability, trademark and document use rules apply.
*/ */
[Exposed=(Window,Worker)] [Exposed=(Window,Worker), Func="IDBFactory::IsEnabled"]
interface IDBDatabase : EventTarget { interface IDBDatabase : EventTarget {
readonly attribute DOMString name; readonly attribute DOMString name;
readonly attribute unsigned long long version; readonly attribute unsigned long long version;

Просмотреть файл

@ -23,7 +23,7 @@ dictionary IDBOpenDBOptions
* http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBFactory * http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBFactory
* for more information. * for more information.
*/ */
[Exposed=(Window,Worker)] [Exposed=(Window,Worker), Func="IDBFactory::IsEnabled"]
interface IDBFactory { interface IDBFactory {
[Throws, NeedsCallerType] [Throws, NeedsCallerType]
IDBOpenDBRequest IDBOpenDBRequest

Просмотреть файл

@ -18,7 +18,7 @@ dictionary IDBIndexParameters {
DOMString? locale = null; DOMString? locale = null;
}; };
[Exposed=(Window,Worker)] [Exposed=(Window,Worker), Func="IDBFactory::IsEnabled"]
interface IDBIndex { interface IDBIndex {
[SetterThrows] [SetterThrows]
attribute DOMString name; attribute DOMString name;

Просмотреть файл

@ -9,7 +9,7 @@
* liability, trademark and document use rules apply. * liability, trademark and document use rules apply.
*/ */
[Exposed=(Window,Worker)] [Exposed=(Window,Worker), Func="IDBFactory::IsEnabled"]
interface IDBKeyRange { interface IDBKeyRange {
[Throws] [Throws]
readonly attribute any lower; readonly attribute any lower;

Просмотреть файл

@ -12,7 +12,7 @@ dictionary IDBObjectStoreParameters {
boolean autoIncrement = false; boolean autoIncrement = false;
}; };
[Exposed=(Window,Worker)] [Exposed=(Window,Worker), Func="IDBFactory::IsEnabled"]
interface IDBObjectStore { interface IDBObjectStore {
[SetterThrows] [SetterThrows]
attribute DOMString name; attribute DOMString name;

Просмотреть файл

@ -7,7 +7,7 @@
* https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBOpenDBRequest * 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 { interface IDBOpenDBRequest : IDBRequest {
attribute EventHandler onblocked; attribute EventHandler onblocked;

Просмотреть файл

@ -13,7 +13,7 @@ enum IDBRequestReadyState {
"done" "done"
}; };
[Exposed=(Window,Worker)] [Exposed=(Window,Worker), Func="IDBFactory::IsEnabled"]
interface IDBRequest : EventTarget { interface IDBRequest : EventTarget {
[Throws] [Throws]
readonly attribute any result; readonly attribute any result;

Просмотреть файл

@ -19,7 +19,7 @@ enum IDBTransactionMode {
"versionchange" "versionchange"
}; };
[Exposed=(Window,Worker)] [Exposed=(Window,Worker), Func="IDBFactory::IsEnabled"]
interface IDBTransaction : EventTarget { interface IDBTransaction : EventTarget {
[Throws] [Throws]
readonly attribute IDBTransactionMode mode; readonly attribute IDBTransactionMode mode;

Просмотреть файл

@ -15,7 +15,7 @@ dictionary IDBVersionChangeEventInit : EventInit {
unsigned long long? newVersion = null; unsigned long long? newVersion = null;
}; };
[Exposed=(Window,Worker)] [Exposed=(Window,Worker), Func="IDBFactory::IsEnabled"]
interface IDBVersionChangeEvent : Event { interface IDBVersionChangeEvent : Event {
constructor(DOMString type, constructor(DOMString type,
optional IDBVersionChangeEventInit eventInitDict = {}); optional IDBVersionChangeEventInit eventInitDict = {});

Просмотреть файл

@ -69,9 +69,9 @@ partial interface mixin WindowOrWorkerGlobalScope {
// http://w3c.github.io/IndexedDB/#factory-interface // http://w3c.github.io/IndexedDB/#factory-interface
partial interface mixin WindowOrWorkerGlobalScope { partial interface mixin WindowOrWorkerGlobalScope {
// readonly attribute IDBFactory indexedDB; // readonly attribute IDBFactory indexedDB; // bug 1776789
[Throws] [Throws, Func="IDBFactory::IsEnabled"]
readonly attribute IDBFactory? indexedDB; readonly attribute IDBFactory? indexedDB;
}; };
// https://w3c.github.io/ServiceWorker/#self-caches // https://w3c.github.io/ServiceWorker/#self-caches

Просмотреть файл

@ -2051,6 +2051,12 @@
value: false value: false
mirror: always 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. # Disable capture attribute for input elements; only supported on GeckoView.
- name: dom.capture.enabled - name: dom.capture.enabled
type: bool type: bool
@ -2534,12 +2540,18 @@
value: false value: false
mirror: always mirror: always
# Enable indexedDB in private browsing mode. # Enable indexedDB in private browsing mode with encryption
- name: dom.indexedDB.privateBrowsing.enabled - name: dom.indexedDB.privateBrowsing.enabled
type: RelaxedAtomicBool type: RelaxedAtomicBool
value: false value: false
mirror: always 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 - name: dom.input_events.beforeinput.enabled
type: bool type: bool
value: true value: true
@ -3594,6 +3606,12 @@
value: false value: false
mirror: always 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 - name: dom.workers.requestAnimationFrame
type: RelaxedAtomicBool type: RelaxedAtomicBool
value: true value: true

Просмотреть файл

@ -26,7 +26,8 @@ AntiTracking.runTestInNormalAndPrivateMode(
resolve() resolve()
); );
}); });
} },
[["dom.indexedDB.hide_in_pbmode.enabled", false]]
); );
AntiTracking.runTestInNormalAndPrivateMode( AntiTracking.runTestInNormalAndPrivateMode(
@ -97,7 +98,7 @@ AntiTracking.runTestInNormalAndPrivateMode(
); );
}); });
}, },
null, [["dom.indexedDB.hide_in_pbmode.enabled", false]],
false, false,
false false
); );

Просмотреть файл

@ -70,5 +70,6 @@ AntiTracking.runTestInNormalAndPrivateMode(
resolve() resolve()
); );
}); });
} },
[["dom.indexedDB.hide_in_pbmode.enabled", false]]
); );

Просмотреть файл

@ -148,7 +148,7 @@ AntiTracking.runTestInNormalAndPrivateMode(
); );
}); });
}, },
null, [["dom.indexedDB.hide_in_pbmode.enabled", false]],
false, false,
false false
); );