[tbb-commits] [Git][tpo/applications/mullvad-browser][mullvad-browser-115.4.0esr-13.0-1] fixup! Bug 42019: Empty browser's clipboard on browser shutdown
ma1 (@ma1)
git at gitlab.torproject.org
Mon Nov 6 22:29:19 UTC 2023
ma1 pushed to branch mullvad-browser-115.4.0esr-13.0-1 at The Tor Project / Applications / Mullvad Browser
Commits:
38f96edf by hackademix at 2023-11-06T23:28:52+01:00
fixup! Bug 42019: Empty browser's clipboard on browser shutdown
Bug 42154: empty clipboard content from private windows on exit.
- - - - -
2 changed files:
- browser/app/profile/001-base-profile.js
- browser/components/BrowserGlue.sys.mjs
Changes:
=====================================
browser/app/profile/001-base-profile.js
=====================================
@@ -87,6 +87,9 @@ pref("browser.sessionstore.resume_from_crash", false);
// Also not needed in PBM at the moment.
pref("browser.pagethumbnails.capturing_disabled", true);
+// Empty clipboard content from private windows on exit (tor-browser#42154)
+pref("browser.privatebrowsing.preserveClipboard", false);
+
// Enable HTTPS-Only mode (tor-browser#19850)
pref("dom.security.https_only_mode", true);
// The previous pref automatically sets this to true (see StaticPrefList.yaml),
=====================================
browser/components/BrowserGlue.sys.mjs
=====================================
@@ -148,6 +148,119 @@ const PRIVATE_BROWSING_EXE_ICON_INDEX = 1;
const PREF_PRIVATE_BROWSING_SHORTCUT_CREATED =
"browser.privacySegmentation.createdShortcut";
+// Empty clipboard content from private windows on exit
+// (tor-browser#42154)
+const ClipboardPrivacy = {
+ _lastClipboardHash: null,
+ _globalActivation: false,
+ _isPrivateClipboard: false,
+ _hasher: null,
+
+ _computeClipboardHash(win = Services.ww.activeWindow) {
+ const trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(
+ Ci.nsITransferable
+ );
+ trans.init(win?.docShell?.QueryInterface(Ci.nsILoadContext) || null);
+ ["text/x-moz-url", "text/plain"].forEach(trans.addDataFlavor);
+ try {
+ Services.clipboard.getData(trans, Ci.nsIClipboard.kGlobalClipboard);
+ const clipboardContent = {};
+ trans.getAnyTransferData({}, clipboardContent);
+ const { data } = clipboardContent.value.QueryInterface(
+ Ci.nsISupportsString
+ );
+ const bytes = new TextEncoder().encode(data);
+ const hasher = (this._hasher ||= Cc[
+ "@mozilla.org/security/hash;1"
+ ].createInstance(Ci.nsICryptoHash));
+ hasher.init(hasher.SHA256);
+ hasher.update(bytes, bytes.length);
+ return hasher.finish(true);
+ } catch (e) {}
+ return null;
+ },
+
+ startup() {
+ this._lastClipboardHash = this._computeClipboardHash();
+
+ // Here we track changes in active window / application,
+ // by filtering focus events and window closures.
+ const handleActivation = (win, activation) => {
+ if (activation) {
+ if (!this._globalActivation) {
+ // focus changed within this window, bail out.
+ return;
+ }
+ this._globalActivation = false;
+ } else if (!Services.focus.activeWindow) {
+ // focus is leaving this window:
+ // let's track whether it remains within the browser.
+ lazy.setTimeout(() => {
+ this._globalActivation = !Services.focus.activeWindow;
+ }, 100);
+ }
+ const clipboardHash = this._computeClipboardHash(win);
+ if (clipboardHash !== this._lastClipboardHash) {
+ this._isPrivateClipboard =
+ !activation &&
+ (lazy.PrivateBrowsingUtils.permanentPrivateBrowsing ||
+ lazy.PrivateBrowsingUtils.isWindowPrivate(win));
+ this._lastClipboardHash = clipboardHash;
+ console.log(
+ `Clipboard changed: private ${this._isPrivateClipboard}, hash ${clipboardHash}.`
+ );
+ }
+ };
+ const focusListener = e =>
+ e.isTrusted && handleActivation(e.currentTarget, e.type === "focusin");
+ const initWindow = win => {
+ for (const e of ["focusin", "focusout"]) {
+ win.addEventListener(e, focusListener);
+ }
+ };
+ for (const w of Services.ww.getWindowEnumerator()) {
+ initWindow(w);
+ }
+ Services.ww.registerNotification((win, event) => {
+ switch (event) {
+ case "domwindowopened":
+ initWindow(win);
+ break;
+ case "domwindowclosed":
+ handleActivation(win, false);
+ if (
+ this._isPrivateClipboard &&
+ lazy.PrivateBrowsingUtils.isWindowPrivate(win) &&
+ !(
+ lazy.PrivateBrowsingUtils.permanentPrivateBrowsing ||
+ Array.from(Services.ww.getWindowEnumerator()).find(w =>
+ lazy.PrivateBrowsingUtils.isWindowPrivate(w)
+ )
+ )
+ ) {
+ // no more private windows, empty private content if needed
+ this.emptyPrivate();
+ }
+ }
+ });
+ },
+ emptyPrivate() {
+ if (
+ this._isPrivateClipboard &&
+ !Services.prefs.getBoolPref(
+ "browser.privatebrowsing.preserveClipboard",
+ false
+ ) &&
+ this._lastClipboardHash === this._computeClipboardHash()
+ ) {
+ Services.clipboard.emptyClipboard(Ci.nsIClipboard.kGlobalClipboard);
+ this._lastClipboardHash = null;
+ this._isPrivateClipboard = false;
+ console.log("Private clipboard emptied.");
+ }
+ },
+};
+
/**
* Fission-compatible JSProcess implementations.
* Each actor options object takes the form of a ProcessActorOptions dictionary.
@@ -1619,6 +1732,8 @@ BrowserGlue.prototype = {
lazy.DoHController.init();
+ ClipboardPrivacy.startup();
+
this._firstWindowTelemetry(aWindow);
this._firstWindowLoaded();
@@ -1879,7 +1994,7 @@ BrowserGlue.prototype = {
lazy.UpdateListener.reset();
}
},
- () => Services.clipboard.emptyClipboard(Ci.nsIClipboard.kGlobalClipboard), // tor-browser#42019
+ () => ClipboardPrivacy.emptyPrivate(), // tor-browser#42019
];
for (let task of tasks) {
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/38f96edf7de0e0e44916dfc9c1fc80978044468b
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/38f96edf7de0e0e44916dfc9c1fc80978044468b
You're receiving this email because of your account on gitlab.torproject.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.torproject.org/pipermail/tbb-commits/attachments/20231106/1c4eab15/attachment-0001.htm>
More information about the tbb-commits
mailing list