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
-
9d4fc4df
by Henry Wilkes at 2023-01-13T10:30:17+00:00
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:
| ... | ... | @@ -15,13 +15,11 @@ const { XPCOMUtils } = ChromeUtils.import( |
| 15 | 15 | "resource://gre/modules/XPCOMUtils.jsm"
|
| 16 | 16 | );
|
| 17 | 17 | |
| 18 | -const kPrefCryptoSafety = "security.cryptoSafety";
|
|
| 19 | - |
|
| 20 | 18 | XPCOMUtils.defineLazyPreferenceGetter(
|
| 21 | 19 | this,
|
| 22 | 20 | "isCryptoSafetyEnabled",
|
| 23 | - kPrefCryptoSafety,
|
|
| 24 | - true /* defaults to true */
|
|
| 21 | + "security.cryptoSafety",
|
|
| 22 | + true // Defaults to true.
|
|
| 25 | 23 | );
|
| 26 | 24 | |
| 27 | 25 | function looksLikeCryptoAddress(s) {
|
| ... | ... | @@ -62,26 +60,28 @@ function looksLikeCryptoAddress(s) { |
| 62 | 60 | |
| 63 | 61 | class CryptoSafetyChild extends JSWindowActorChild {
|
| 64 | 62 | handleEvent(event) {
|
| 65 | - if (isCryptoSafetyEnabled) {
|
|
| 66 | - // Ignore non-HTTP addresses
|
|
| 67 | - if (!this.document.documentURIObject.schemeIs("http")) {
|
|
| 68 | - return;
|
|
| 69 | - }
|
|
| 70 | - // Ignore onion addresses
|
|
| 71 | - if (this.document.documentURIObject.host.endsWith(".onion")) {
|
|
| 72 | - return;
|
|
| 73 | - }
|
|
| 63 | + if (
|
|
| 64 | + !isCryptoSafetyEnabled ||
|
|
| 65 | + // Ignore non-HTTP addresses.
|
|
| 66 | + // We do this before reading the host property since this is not available
|
|
| 67 | + // for about: pages.
|
|
| 68 | + !this.document.documentURIObject.schemeIs("http") ||
|
|
| 69 | + // Ignore onion addresses.
|
|
| 70 | + this.document.documentURIObject.host.endsWith(".onion") ||
|
|
| 71 | + (event.type !== "copy" && event.type !== "cut")
|
|
| 72 | + ) {
|
|
| 73 | + return;
|
|
| 74 | + }
|
|
| 74 | 75 | |
| 75 | - if (event.type == "copy" || event.type == "cut") {
|
|
| 76 | - this.contentWindow.navigator.clipboard.readText().then(clipText => {
|
|
| 77 | - const selection = clipText.replace(/\s+/g, "");
|
|
| 78 | - if (looksLikeCryptoAddress(selection)) {
|
|
| 79 | - this.sendAsyncMessage("CryptoSafety:CopiedText", {
|
|
| 80 | - selection,
|
|
| 81 | - });
|
|
| 82 | - }
|
|
| 83 | - });
|
|
| 76 | + this.contentWindow.navigator.clipboard.readText().then(clipText => {
|
|
| 77 | + const selection = clipText.replace(/\s+/g, "");
|
|
| 78 | + if (!looksLikeCryptoAddress(selection)) {
|
|
| 79 | + return;
|
|
| 84 | 80 | }
|
| 85 | - }
|
|
| 81 | + this.sendAsyncMessage("CryptoSafety:CopiedText", {
|
|
| 82 | + selection,
|
|
| 83 | + host: this.document.documentURIObject.host,
|
|
| 84 | + });
|
|
| 85 | + });
|
|
| 86 | 86 | }
|
| 87 | 87 | } |
| ... | ... | @@ -7,136 +7,75 @@ |
| 7 | 7 | |
| 8 | 8 | var EXPORTED_SYMBOLS = ["CryptoSafetyParent"];
|
| 9 | 9 | |
| 10 | +const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|
| 10 | 11 | const { XPCOMUtils } = ChromeUtils.import(
|
| 11 | 12 | "resource://gre/modules/XPCOMUtils.jsm"
|
| 12 | 13 | );
|
| 13 | 14 | |
| 14 | -XPCOMUtils.defineLazyModuleGetters(this, {
|
|
| 15 | - TorStrings: "resource:///modules/TorStrings.jsm",
|
|
| 15 | +XPCOMUtils.defineLazyGetter(this, "cryptoSafetyBundle", () => {
|
|
| 16 | + return Services.strings.createBundle(
|
|
| 17 | + "chrome://torbutton/locale/cryptoSafetyPrompt.properties"
|
|
| 18 | + );
|
|
| 16 | 19 | });
|
| 17 | 20 | |
| 18 | -const kPrefCryptoSafety = "security.cryptoSafety";
|
|
| 21 | +// en-US fallback in case a locale is missing a string.
|
|
| 22 | +XPCOMUtils.defineLazyGetter(this, "fallbackCryptoSafetyBundle", () => {
|
|
| 23 | + return Services.strings.createBundle(
|
|
| 24 | + "resource://gre/chrome/torbutton/locale/en-US/cryptoSafetyPrompt.properties"
|
|
| 25 | + );
|
|
| 26 | +});
|
|
| 19 | 27 | |
| 20 | 28 | XPCOMUtils.defineLazyPreferenceGetter(
|
| 21 | 29 | this,
|
| 22 | 30 | "isCryptoSafetyEnabled",
|
| 23 | - kPrefCryptoSafety,
|
|
| 24 | - true /* defaults to true */
|
|
| 31 | + "security.cryptoSafety",
|
|
| 32 | + true // Defaults to true.
|
|
| 25 | 33 | );
|
| 26 | 34 | |
| 27 | -class CryptoSafetyParent extends JSWindowActorParent {
|
|
| 28 | - getBrowser() {
|
|
| 29 | - return this.browsingContext.top.embedderElement;
|
|
| 30 | - }
|
|
| 31 | - |
|
| 32 | - receiveMessage(aMessage) {
|
|
| 33 | - if (isCryptoSafetyEnabled) {
|
|
| 34 | - if (aMessage.name == "CryptoSafety:CopiedText") {
|
|
| 35 | - showPopup(this.getBrowser(), aMessage.data.selection);
|
|
| 36 | - }
|
|
| 37 | - }
|
|
| 38 | - }
|
|
| 39 | -}
|
|
| 40 | - |
|
| 41 | -function trimAddress(cryptoAddr) {
|
|
| 42 | - if (cryptoAddr.length <= 32) {
|
|
| 43 | - return cryptoAddr;
|
|
| 44 | - }
|
|
| 45 | - return cryptoAddr.substring(0, 32) + "...";
|
|
| 46 | -}
|
|
| 47 | - |
|
| 48 | -function showPopup(aBrowser, cryptoAddr) {
|
|
| 49 | - const chromeDoc = aBrowser.ownerDocument;
|
|
| 50 | - if (chromeDoc) {
|
|
| 51 | - const win = chromeDoc.defaultView;
|
|
| 52 | - const cryptoSafetyPrompt = new CryptoSafetyPrompt(
|
|
| 53 | - aBrowser,
|
|
| 54 | - win,
|
|
| 55 | - cryptoAddr
|
|
| 56 | - );
|
|
| 57 | - cryptoSafetyPrompt.show();
|
|
| 35 | +/**
|
|
| 36 | + * Get a formatted string from the locale's bundle, or the en-US bundle if the
|
|
| 37 | + * string is missing.
|
|
| 38 | + *
|
|
| 39 | + * @param {string} name - The string's name.
|
|
| 40 | + * @param {string[]} [args] - Positional arguments to pass to the format string,
|
|
| 41 | + * or leave empty if none are needed.
|
|
| 42 | + *
|
|
| 43 | + * @returns {string} - The formatted string.
|
|
| 44 | + */
|
|
| 45 | +function getString(name, args = []) {
|
|
| 46 | + try {
|
|
| 47 | + return cryptoSafetyBundle.formatStringFromName(name, args);
|
|
| 48 | + } catch {
|
|
| 49 | + return fallbackCryptoSafetyBundle.formatStringFromName(name, args);
|
|
| 58 | 50 | }
|
| 59 | 51 | }
|
| 60 | 52 | |
| 61 | -class CryptoSafetyPrompt {
|
|
| 62 | - constructor(aBrowser, aWin, cryptoAddr) {
|
|
| 63 | - this._browser = aBrowser;
|
|
| 64 | - this._win = aWin;
|
|
| 65 | - this._cryptoAddr = cryptoAddr;
|
|
| 66 | - }
|
|
| 67 | - |
|
| 68 | - show() {
|
|
| 69 | - const primaryAction = {
|
|
| 70 | - label: TorStrings.cryptoSafetyPrompt.primaryAction,
|
|
| 71 | - accessKey: TorStrings.cryptoSafetyPrompt.primaryActionAccessKey,
|
|
| 72 | - callback: () => {
|
|
| 73 | - this._win.torbutton_new_circuit();
|
|
| 74 | - },
|
|
| 75 | - };
|
|
| 76 | - |
|
| 77 | - const secondaryAction = {
|
|
| 78 | - label: TorStrings.cryptoSafetyPrompt.secondaryAction,
|
|
| 79 | - accessKey: TorStrings.cryptoSafetyPrompt.secondaryActionAccessKey,
|
|
| 80 | - callback: () => {},
|
|
| 81 | - };
|
|
| 82 | - |
|
| 83 | - let _this = this;
|
|
| 84 | - const options = {
|
|
| 85 | - popupIconURL: "chrome://global/skin/icons/warning.svg",
|
|
| 86 | - eventCallback(aTopic) {
|
|
| 87 | - if (aTopic === "showing") {
|
|
| 88 | - _this._onPromptShowing();
|
|
| 89 | - }
|
|
| 90 | - },
|
|
| 91 | - };
|
|
| 92 | - |
|
| 93 | - const cryptoWarningText = TorStrings.cryptoSafetyPrompt.cryptoWarning.replace(
|
|
| 94 | - "%S",
|
|
| 95 | - trimAddress(this._cryptoAddr)
|
|
| 96 | - );
|
|
| 97 | - |
|
| 98 | - if (this._win.PopupNotifications) {
|
|
| 99 | - this._prompt = this._win.PopupNotifications.show(
|
|
| 100 | - this._browser,
|
|
| 101 | - "crypto-safety-warning",
|
|
| 102 | - cryptoWarningText,
|
|
| 103 | - null /* anchor ID */,
|
|
| 104 | - primaryAction,
|
|
| 105 | - [secondaryAction],
|
|
| 106 | - options
|
|
| 107 | - );
|
|
| 53 | +class CryptoSafetyParent extends JSWindowActorParent {
|
|
| 54 | + receiveMessage(aMessage) {
|
|
| 55 | + if (!isCryptoSafetyEnabled || aMessage.name !== "CryptoSafety:CopiedText") {
|
|
| 56 | + return;
|
|
| 108 | 57 | }
|
| 109 | - }
|
|
| 110 | - |
|
| 111 | - _onPromptShowing() {
|
|
| 112 | - let xulDoc = this._browser.ownerDocument;
|
|
| 113 | 58 | |
| 114 | - let whatCanHeading = xulDoc.getElementById(
|
|
| 115 | - "crypto-safety-warning-notification-what-can-heading"
|
|
| 116 | - );
|
|
| 117 | - if (whatCanHeading) {
|
|
| 118 | - whatCanHeading.textContent = TorStrings.cryptoSafetyPrompt.whatCanHeading;
|
|
| 59 | + let address = aMessage.data.selection;
|
|
| 60 | + if (address.length > 32) {
|
|
| 61 | + address = `${address.substring(0, 32)}…`;
|
|
| 119 | 62 | }
|
| 120 | 63 | |
| 121 | - let whatCanBody = xulDoc.getElementById(
|
|
| 122 | - "crypto-safety-warning-notification-what-can-body"
|
|
| 64 | + const buttonPressed = Services.prompt.confirmEx(
|
|
| 65 | + this.browsingContext.topChromeWindow,
|
|
| 66 | + getString("cryptoSafetyPrompt.cryptoTitle"),
|
|
| 67 | + getString("cryptoSafetyPrompt.cryptoBody", [address, aMessage.data.host]),
|
|
| 68 | + Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_0 +
|
|
| 69 | + Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_1,
|
|
| 70 | + getString("cryptoSafetyPrompt.primaryAction"),
|
|
| 71 | + getString("cryptoSafetyPrompt.secondaryAction"),
|
|
| 72 | + null,
|
|
| 73 | + null,
|
|
| 74 | + {}
|
|
| 123 | 75 | );
|
| 124 | - if (whatCanBody) {
|
|
| 125 | - whatCanBody.textContent = TorStrings.cryptoSafetyPrompt.whatCanBody;
|
|
| 126 | - }
|
|
| 127 | 76 | |
| 128 | - let learnMoreElem = xulDoc.getElementById(
|
|
| 129 | - "crypto-safety-warning-notification-learnmore"
|
|
| 130 | - );
|
|
| 131 | - if (learnMoreElem) {
|
|
| 132 | - learnMoreElem.setAttribute(
|
|
| 133 | - "value",
|
|
| 134 | - TorStrings.cryptoSafetyPrompt.learnMore
|
|
| 135 | - );
|
|
| 136 | - learnMoreElem.setAttribute(
|
|
| 137 | - "href",
|
|
| 138 | - TorStrings.cryptoSafetyPrompt.learnMoreURL
|
|
| 139 | - );
|
|
| 77 | + if (buttonPressed === 0) {
|
|
| 78 | + this.browsingContext.topChromeWindow.torbutton_new_circuit();
|
|
| 140 | 79 | }
|
| 141 | 80 | }
|
| 142 | 81 | } |
| ... | ... | @@ -166,17 +166,3 @@ |
| 166 | 166 | </vbox>
|
| 167 | 167 | </popupnotificationfooter>
|
| 168 | 168 | </popupnotification> |
| 169 | - |
|
| 170 | - <popupnotification id="crypto-safety-warning-notification" hidden="true">
|
|
| 171 | - <popupnotificationcontent orient="vertical">
|
|
| 172 | - <description id="crypto-safety-warning-notification-desc"/>
|
|
| 173 | - <html:div id="crypto-safety-warning-notification-what-can">
|
|
| 174 | - <html:strong id="crypto-safety-warning-notification-what-can-heading" />
|
|
| 175 | - <html:br/>
|
|
| 176 | - <html:span id="crypto-safety-warning-notification-what-can-body" />
|
|
| 177 | - </html:div>
|
|
| 178 | - <label id="crypto-safety-warning-notification-learnmore"
|
|
| 179 | - class="popup-notification-learnmore-link"
|
|
| 180 | - is="text-link"/>
|
|
| 181 | - </popupnotificationcontent>
|
|
| 182 | - </popupnotification> |
| ... | ... | @@ -67,40 +67,6 @@ class TorPropertyStringBundle { |
| 67 | 67 | }
|
| 68 | 68 | |
| 69 | 69 | const Loader = {
|
| 70 | - /*
|
|
| 71 | - CryptoSafetyPrompt Strings
|
|
| 72 | - */
|
|
| 73 | - cryptoSafetyPrompt() {
|
|
| 74 | - const tsb = new TorPropertyStringBundle(
|
|
| 75 | - "chrome://torbutton/locale/cryptoSafetyPrompt.properties",
|
|
| 76 | - "cryptoSafetyPrompt."
|
|
| 77 | - );
|
|
| 78 | - const getString = tsb.getString.bind(tsb);
|
|
| 79 | - |
|
| 80 | - const retval = {
|
|
| 81 | - cryptoWarning: getString(
|
|
| 82 | - "cryptoWarning",
|
|
| 83 | - "A cryptocurrency address (%S) has been copied from an insecure website. It could have been modified."
|
|
| 84 | - ),
|
|
| 85 | - whatCanHeading: getString("whatCanHeading", "What can you do about it?"),
|
|
| 86 | - whatCanBody: getString(
|
|
| 87 | - "whatCanBody",
|
|
| 88 | - "You can try reconnecting with a new circuit to establish a secure connection, or accept the risk and dismiss this warning."
|
|
| 89 | - ),
|
|
| 90 | - learnMore: getString("learnMore", "Learn more"),
|
|
| 91 | - learnMoreURL: `https://support.torproject.org/${getLocale()}/`,
|
|
| 92 | - primaryAction: getString(
|
|
| 93 | - "primaryAction",
|
|
| 94 | - "Reload Tab with a New Circuit"
|
|
| 95 | - ),
|
|
| 96 | - primaryActionAccessKey: getString("primaryActionAccessKey", "R"),
|
|
| 97 | - secondaryAction: getString("secondaryAction", "Dismiss Warning"),
|
|
| 98 | - secondaryActionAccessKey: getString("secondaryActionAccessKey", "D"),
|
|
| 99 | - };
|
|
| 100 | - |
|
| 101 | - return retval;
|
|
| 102 | - } /* CryptoSafetyPrompt Strings */,
|
|
| 103 | - |
|
| 104 | 70 | /*
|
| 105 | 71 | Tor about:preferences#connection Strings
|
| 106 | 72 | */
|
| ... | ... | @@ -575,13 +541,6 @@ const Loader = { |
| 575 | 541 | };
|
| 576 | 542 | |
| 577 | 543 | const TorStrings = {
|
| 578 | - get cryptoSafetyPrompt() {
|
|
| 579 | - if (!this._cryptoSafetyPrompt) {
|
|
| 580 | - this._cryptoSafetyPrompt = Loader.cryptoSafetyPrompt();
|
|
| 581 | - }
|
|
| 582 | - return this._cryptoSafetyPrompt;
|
|
| 583 | - },
|
|
| 584 | - |
|
| 585 | 544 | get settings() {
|
| 586 | 545 | if (!this._settings) {
|
| 587 | 546 | this._settings = Loader.settings();
|
| ... | ... | @@ -831,8 +831,3 @@ popupnotificationcontent { |
| 831 | 831 | #tab-notification-deck {
|
| 832 | 832 | display: block;
|
| 833 | 833 | } |
| 834 | - |
|
| 835 | -#crypto-safety-warning-notification-what-can {
|
|
| 836 | - display: block;
|
|
| 837 | - margin: 5px;
|
|
| 838 | -} |
| ... | ... | @@ -3,6 +3,11 @@ |
| 3 | 3 | # License, v. 2.0. If a copy of the MPL was not distributed with this
|
| 4 | 4 | # file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
| 5 | 5 | |
| 6 | +cryptoSafetyPrompt.cryptoTitle=Cryptocurrency address copied from an insecure website
|
|
| 7 | +# LOCALIZATION NOTE:
|
|
| 8 | +# %1$S is the copied cryptocurrency address.
|
|
| 9 | +# %2$S is the website host.
|
|
| 10 | +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.
|
|
| 6 | 11 | # LOCALIZATION NOTE: %S will be replaced with the cryptocurrency address.
|
| 7 | 12 | cryptoSafetyPrompt.cryptoWarning=A cryptocurrency address (%S) has been copied from an insecure website. It could have been modified.
|
| 8 | 13 | cryptoSafetyPrompt.whatCanHeading=What can you do about it?
|