Pier Angelo Vendrame pushed to branch tor-browser-102.6.0esr-12.5-1 at The Tor Project / Applications / Tor Browser
Commits: 7ccf0766 by Henry Wilkes at 2023-01-13T10:30:16+00:00 fixup! Bug 40209: Implement Basic Crypto Safety
Bug 41363: Use a notification dialog instead of the popup notification.
- - - - - 9d4fc4df by Henry Wilkes at 2023-01-13T10:30:17+00:00 fixup! Add TorStrings module for localization
Bug 32274: Remove crypto prompt from TorStrings.jsm
- - - - -
6 changed files:
- browser/actors/CryptoSafetyChild.jsm - browser/actors/CryptoSafetyParent.jsm - browser/base/content/popup-notifications.inc - browser/modules/TorStrings.jsm - browser/themes/shared/browser-shared.css - toolkit/torbutton/chrome/locale/en-US/cryptoSafetyPrompt.properties
Changes:
===================================== browser/actors/CryptoSafetyChild.jsm ===================================== @@ -15,13 +15,11 @@ const { XPCOMUtils } = ChromeUtils.import( "resource://gre/modules/XPCOMUtils.jsm" );
-const kPrefCryptoSafety = "security.cryptoSafety"; - XPCOMUtils.defineLazyPreferenceGetter( this, "isCryptoSafetyEnabled", - kPrefCryptoSafety, - true /* defaults to true */ + "security.cryptoSafety", + true // Defaults to true. );
function looksLikeCryptoAddress(s) { @@ -62,26 +60,28 @@ function looksLikeCryptoAddress(s) {
class CryptoSafetyChild extends JSWindowActorChild { handleEvent(event) { - if (isCryptoSafetyEnabled) { - // Ignore non-HTTP addresses - if (!this.document.documentURIObject.schemeIs("http")) { - return; - } - // Ignore onion addresses - if (this.document.documentURIObject.host.endsWith(".onion")) { - return; - } + if ( + !isCryptoSafetyEnabled || + // Ignore non-HTTP addresses. + // We do this before reading the host property since this is not available + // for about: pages. + !this.document.documentURIObject.schemeIs("http") || + // Ignore onion addresses. + this.document.documentURIObject.host.endsWith(".onion") || + (event.type !== "copy" && event.type !== "cut") + ) { + return; + }
- if (event.type == "copy" || event.type == "cut") { - this.contentWindow.navigator.clipboard.readText().then(clipText => { - const selection = clipText.replace(/\s+/g, ""); - if (looksLikeCryptoAddress(selection)) { - this.sendAsyncMessage("CryptoSafety:CopiedText", { - selection, - }); - } - }); + this.contentWindow.navigator.clipboard.readText().then(clipText => { + const selection = clipText.replace(/\s+/g, ""); + if (!looksLikeCryptoAddress(selection)) { + return; } - } + this.sendAsyncMessage("CryptoSafety:CopiedText", { + selection, + host: this.document.documentURIObject.host, + }); + }); } }
===================================== browser/actors/CryptoSafetyParent.jsm ===================================== @@ -7,136 +7,75 @@
var EXPORTED_SYMBOLS = ["CryptoSafetyParent"];
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); const { XPCOMUtils } = ChromeUtils.import( "resource://gre/modules/XPCOMUtils.jsm" );
-XPCOMUtils.defineLazyModuleGetters(this, { - TorStrings: "resource:///modules/TorStrings.jsm", +XPCOMUtils.defineLazyGetter(this, "cryptoSafetyBundle", () => { + return Services.strings.createBundle( + "chrome://torbutton/locale/cryptoSafetyPrompt.properties" + ); });
-const kPrefCryptoSafety = "security.cryptoSafety"; +// en-US fallback in case a locale is missing a string. +XPCOMUtils.defineLazyGetter(this, "fallbackCryptoSafetyBundle", () => { + return Services.strings.createBundle( + "resource://gre/chrome/torbutton/locale/en-US/cryptoSafetyPrompt.properties" + ); +});
XPCOMUtils.defineLazyPreferenceGetter( this, "isCryptoSafetyEnabled", - kPrefCryptoSafety, - true /* defaults to true */ + "security.cryptoSafety", + true // Defaults to true. );
-class CryptoSafetyParent extends JSWindowActorParent { - getBrowser() { - return this.browsingContext.top.embedderElement; - } - - receiveMessage(aMessage) { - if (isCryptoSafetyEnabled) { - if (aMessage.name == "CryptoSafety:CopiedText") { - showPopup(this.getBrowser(), aMessage.data.selection); - } - } - } -} - -function trimAddress(cryptoAddr) { - if (cryptoAddr.length <= 32) { - return cryptoAddr; - } - return cryptoAddr.substring(0, 32) + "..."; -} - -function showPopup(aBrowser, cryptoAddr) { - const chromeDoc = aBrowser.ownerDocument; - if (chromeDoc) { - const win = chromeDoc.defaultView; - const cryptoSafetyPrompt = new CryptoSafetyPrompt( - aBrowser, - win, - cryptoAddr - ); - cryptoSafetyPrompt.show(); +/** + * Get a formatted string from the locale's bundle, or the en-US bundle if the + * string is missing. + * + * @param {string} name - The string's name. + * @param {string[]} [args] - Positional arguments to pass to the format string, + * or leave empty if none are needed. + * + * @returns {string} - The formatted string. + */ +function getString(name, args = []) { + try { + return cryptoSafetyBundle.formatStringFromName(name, args); + } catch { + return fallbackCryptoSafetyBundle.formatStringFromName(name, args); } }
-class CryptoSafetyPrompt { - constructor(aBrowser, aWin, cryptoAddr) { - this._browser = aBrowser; - this._win = aWin; - this._cryptoAddr = cryptoAddr; - } - - show() { - const primaryAction = { - label: TorStrings.cryptoSafetyPrompt.primaryAction, - accessKey: TorStrings.cryptoSafetyPrompt.primaryActionAccessKey, - callback: () => { - this._win.torbutton_new_circuit(); - }, - }; - - const secondaryAction = { - label: TorStrings.cryptoSafetyPrompt.secondaryAction, - accessKey: TorStrings.cryptoSafetyPrompt.secondaryActionAccessKey, - callback: () => {}, - }; - - let _this = this; - const options = { - popupIconURL: "chrome://global/skin/icons/warning.svg", - eventCallback(aTopic) { - if (aTopic === "showing") { - _this._onPromptShowing(); - } - }, - }; - - const cryptoWarningText = TorStrings.cryptoSafetyPrompt.cryptoWarning.replace( - "%S", - trimAddress(this._cryptoAddr) - ); - - if (this._win.PopupNotifications) { - this._prompt = this._win.PopupNotifications.show( - this._browser, - "crypto-safety-warning", - cryptoWarningText, - null /* anchor ID */, - primaryAction, - [secondaryAction], - options - ); +class CryptoSafetyParent extends JSWindowActorParent { + receiveMessage(aMessage) { + if (!isCryptoSafetyEnabled || aMessage.name !== "CryptoSafety:CopiedText") { + return; } - } - - _onPromptShowing() { - let xulDoc = this._browser.ownerDocument;
- let whatCanHeading = xulDoc.getElementById( - "crypto-safety-warning-notification-what-can-heading" - ); - if (whatCanHeading) { - whatCanHeading.textContent = TorStrings.cryptoSafetyPrompt.whatCanHeading; + let address = aMessage.data.selection; + if (address.length > 32) { + address = `${address.substring(0, 32)}…`; }
- let whatCanBody = xulDoc.getElementById( - "crypto-safety-warning-notification-what-can-body" + const buttonPressed = Services.prompt.confirmEx( + this.browsingContext.topChromeWindow, + getString("cryptoSafetyPrompt.cryptoTitle"), + getString("cryptoSafetyPrompt.cryptoBody", [address, aMessage.data.host]), + Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_0 + + Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_1, + getString("cryptoSafetyPrompt.primaryAction"), + getString("cryptoSafetyPrompt.secondaryAction"), + null, + null, + {} ); - if (whatCanBody) { - whatCanBody.textContent = TorStrings.cryptoSafetyPrompt.whatCanBody; - }
- let learnMoreElem = xulDoc.getElementById( - "crypto-safety-warning-notification-learnmore" - ); - if (learnMoreElem) { - learnMoreElem.setAttribute( - "value", - TorStrings.cryptoSafetyPrompt.learnMore - ); - learnMoreElem.setAttribute( - "href", - TorStrings.cryptoSafetyPrompt.learnMoreURL - ); + if (buttonPressed === 0) { + this.browsingContext.topChromeWindow.torbutton_new_circuit(); } } }
===================================== browser/base/content/popup-notifications.inc ===================================== @@ -166,17 +166,3 @@ </vbox> </popupnotificationfooter> </popupnotification> - - <popupnotification id="crypto-safety-warning-notification" hidden="true"> - <popupnotificationcontent orient="vertical"> - <description id="crypto-safety-warning-notification-desc"/> - <html:div id="crypto-safety-warning-notification-what-can"> - <html:strong id="crypto-safety-warning-notification-what-can-heading" /> - html:br/ - <html:span id="crypto-safety-warning-notification-what-can-body" /> - </html:div> - <label id="crypto-safety-warning-notification-learnmore" - class="popup-notification-learnmore-link" - is="text-link"/> - </popupnotificationcontent> - </popupnotification>
===================================== browser/modules/TorStrings.jsm ===================================== @@ -67,40 +67,6 @@ class TorPropertyStringBundle { }
const Loader = { - /* - CryptoSafetyPrompt Strings - */ - cryptoSafetyPrompt() { - const tsb = new TorPropertyStringBundle( - "chrome://torbutton/locale/cryptoSafetyPrompt.properties", - "cryptoSafetyPrompt." - ); - const getString = tsb.getString.bind(tsb); - - const retval = { - cryptoWarning: getString( - "cryptoWarning", - "A cryptocurrency address (%S) has been copied from an insecure website. It could have been modified." - ), - whatCanHeading: getString("whatCanHeading", "What can you do about it?"), - whatCanBody: getString( - "whatCanBody", - "You can try reconnecting with a new circuit to establish a secure connection, or accept the risk and dismiss this warning." - ), - learnMore: getString("learnMore", "Learn more"), - learnMoreURL: `https://support.torproject.org/$%7BgetLocale()%7D/%60, - primaryAction: getString( - "primaryAction", - "Reload Tab with a New Circuit" - ), - primaryActionAccessKey: getString("primaryActionAccessKey", "R"), - secondaryAction: getString("secondaryAction", "Dismiss Warning"), - secondaryActionAccessKey: getString("secondaryActionAccessKey", "D"), - }; - - return retval; - } /* CryptoSafetyPrompt Strings */, - /* Tor about:preferences#connection Strings */ @@ -575,13 +541,6 @@ const Loader = { };
const TorStrings = { - get cryptoSafetyPrompt() { - if (!this._cryptoSafetyPrompt) { - this._cryptoSafetyPrompt = Loader.cryptoSafetyPrompt(); - } - return this._cryptoSafetyPrompt; - }, - get settings() { if (!this._settings) { this._settings = Loader.settings();
===================================== browser/themes/shared/browser-shared.css ===================================== @@ -831,8 +831,3 @@ popupnotificationcontent { #tab-notification-deck { display: block; } - -#crypto-safety-warning-notification-what-can { - display: block; - margin: 5px; -}
===================================== toolkit/torbutton/chrome/locale/en-US/cryptoSafetyPrompt.properties ===================================== @@ -3,6 +3,11 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+cryptoSafetyPrompt.cryptoTitle=Cryptocurrency address copied from an insecure website +# LOCALIZATION NOTE: +# %1$S is the copied cryptocurrency address. +# %2$S is the website host. +cryptoSafetyPrompt.cryptoBody=The copied text (%1$S) appears to be a cryptocurrency address. Since the connection to %2$S is not secure, the address may have been modified and should not be trusted. You can try establishing a secure connection by reconnecting with a new circuit. # LOCALIZATION NOTE: %S will be replaced with the cryptocurrency address.. cryptoSafetyPrompt.cryptoWarning=A cryptocurrency address (%S) has been copied from an insecure website. It could have been modified. cryptoSafetyPrompt.whatCanHeading=What can you do about it?
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/a191ab7...