ma1 pushed to branch tor-browser-128.2.0esr-14.0-1 at The Tor Project / Applications / Tor Browser
Commits:
-
cbb6af14
by Henry Wilkes at 2024-09-12T10:51:21+01:00
2 changed files:
Changes:
| ... | ... | @@ -5,12 +5,14 @@ |
| 5 | 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this
|
| 6 | 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
| 7 | 7 | |
| 8 | -import { Bech32Decode } from "resource://gre/modules/Bech32Decode.sys.mjs";
|
|
| 9 | - |
|
| 10 | 8 | import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
|
| 11 | 9 | |
| 12 | 10 | const lazy = {};
|
| 13 | 11 | |
| 12 | +ChromeUtils.defineESModuleGetters(lazy, {
|
|
| 13 | + setTimeout: "resource://gre/modules/Timer.sys.mjs",
|
|
| 14 | +});
|
|
| 15 | + |
|
| 14 | 16 | XPCOMUtils.defineLazyPreferenceGetter(
|
| 15 | 17 | lazy,
|
| 16 | 18 | "isCryptoSafetyEnabled",
|
| ... | ... | @@ -18,43 +20,6 @@ XPCOMUtils.defineLazyPreferenceGetter( |
| 18 | 20 | true // Defaults to true.
|
| 19 | 21 | );
|
| 20 | 22 | |
| 21 | -function looksLikeCryptoAddress(s) {
|
|
| 22 | - // P2PKH and P2SH addresses
|
|
| 23 | - // https://stackoverflow.com/a/24205650
|
|
| 24 | - const bitcoinAddr = /^[13][a-km-zA-HJ-NP-Z1-9]{25,39}$/;
|
|
| 25 | - if (bitcoinAddr.test(s)) {
|
|
| 26 | - return true;
|
|
| 27 | - }
|
|
| 28 | - |
|
| 29 | - // Bech32 addresses
|
|
| 30 | - if (Bech32Decode(s) !== null) {
|
|
| 31 | - return true;
|
|
| 32 | - }
|
|
| 33 | - |
|
| 34 | - // regular addresses
|
|
| 35 | - const etherAddr = /^0x[a-fA-F0-9]{40}$/;
|
|
| 36 | - if (etherAddr.test(s)) {
|
|
| 37 | - return true;
|
|
| 38 | - }
|
|
| 39 | - |
|
| 40 | - // t-addresses
|
|
| 41 | - // https://www.reddit.com/r/zec/comments/8mxj6x/simple_regex_to_validate_a_zcash_tz_address/dzr62p5/
|
|
| 42 | - const zcashAddr = /^t1[a-zA-Z0-9]{33}$/;
|
|
| 43 | - if (zcashAddr.test(s)) {
|
|
| 44 | - return true;
|
|
| 45 | - }
|
|
| 46 | - |
|
| 47 | - // Standard, Integrated, and 256-bit Integrated addresses
|
|
| 48 | - // https://monero.stackexchange.com/a/10627
|
|
| 49 | - const moneroAddr =
|
|
| 50 | - /^4(?:[0-9AB]|[1-9A-HJ-NP-Za-km-z]{12}(?:[1-9A-HJ-NP-Za-km-z]{30})?)[1-9A-HJ-NP-Za-km-z]{93}$/;
|
|
| 51 | - if (moneroAddr.test(s)) {
|
|
| 52 | - return true;
|
|
| 53 | - }
|
|
| 54 | - |
|
| 55 | - return false;
|
|
| 56 | -}
|
|
| 57 | - |
|
| 58 | 23 | export class CryptoSafetyChild extends JSWindowActorChild {
|
| 59 | 24 | handleEvent(event) {
|
| 60 | 25 | if (
|
| ... | ... | @@ -70,13 +35,13 @@ export class CryptoSafetyChild extends JSWindowActorChild { |
| 70 | 35 | return;
|
| 71 | 36 | }
|
| 72 | 37 | |
| 73 | - this.contentWindow.navigator.clipboard.readText().then(clipText => {
|
|
| 74 | - const selection = clipText.replace(/\s+/g, "");
|
|
| 75 | - if (!looksLikeCryptoAddress(selection)) {
|
|
| 76 | - return;
|
|
| 77 | - }
|
|
| 38 | + // We send a message to the parent to inspect the clipboard content.
|
|
| 39 | + // NOTE: We wait until next cycle to allow the event to propagate and fill
|
|
| 40 | + // the clipboard before being read.
|
|
| 41 | + // NOTE: Using navigator.clipboard.readText fails with Wayland. See
|
|
| 42 | + // tor-browser#42702.
|
|
| 43 | + lazy.setTimeout(() => {
|
|
| 78 | 44 | this.sendAsyncMessage("CryptoSafety:CopiedText", {
|
| 79 | - selection,
|
|
| 80 | 45 | host: this.document.documentURIObject.host,
|
| 81 | 46 | });
|
| 82 | 47 | });
|
| ... | ... | @@ -11,6 +11,7 @@ const lazy = {}; |
| 11 | 11 | |
| 12 | 12 | ChromeUtils.defineESModuleGetters(lazy, {
|
| 13 | 13 | TorDomainIsolator: "resource://gre/modules/TorDomainIsolator.sys.mjs",
|
| 14 | + Bech32Decode: "resource://gre/modules/Bech32Decode.sys.mjs",
|
|
| 14 | 15 | });
|
| 15 | 16 | |
| 16 | 17 | ChromeUtils.defineLazyGetter(lazy, "CryptoStrings", function () {
|
| ... | ... | @@ -24,6 +25,43 @@ XPCOMUtils.defineLazyPreferenceGetter( |
| 24 | 25 | true // Defaults to true.
|
| 25 | 26 | );
|
| 26 | 27 | |
| 28 | +function looksLikeCryptoAddress(s) {
|
|
| 29 | + // P2PKH and P2SH addresses
|
|
| 30 | + // https://stackoverflow.com/a/24205650
|
|
| 31 | + const bitcoinAddr = /^[13][a-km-zA-HJ-NP-Z1-9]{25,39}$/;
|
|
| 32 | + if (bitcoinAddr.test(s)) {
|
|
| 33 | + return true;
|
|
| 34 | + }
|
|
| 35 | + |
|
| 36 | + // Bech32 addresses
|
|
| 37 | + if (lazy.Bech32Decode(s) !== null) {
|
|
| 38 | + return true;
|
|
| 39 | + }
|
|
| 40 | + |
|
| 41 | + // regular addresses
|
|
| 42 | + const etherAddr = /^0x[a-fA-F0-9]{40}$/;
|
|
| 43 | + if (etherAddr.test(s)) {
|
|
| 44 | + return true;
|
|
| 45 | + }
|
|
| 46 | + |
|
| 47 | + // t-addresses
|
|
| 48 | + // https://www.reddit.com/r/zec/comments/8mxj6x/simple_regex_to_validate_a_zcash_tz_address/dzr62p5/
|
|
| 49 | + const zcashAddr = /^t1[a-zA-Z0-9]{33}$/;
|
|
| 50 | + if (zcashAddr.test(s)) {
|
|
| 51 | + return true;
|
|
| 52 | + }
|
|
| 53 | + |
|
| 54 | + // Standard, Integrated, and 256-bit Integrated addresses
|
|
| 55 | + // https://monero.stackexchange.com/a/10627
|
|
| 56 | + const moneroAddr =
|
|
| 57 | + /^4(?:[0-9AB]|[1-9A-HJ-NP-Za-km-z]{12}(?:[1-9A-HJ-NP-Za-km-z]{30})?)[1-9A-HJ-NP-Za-km-z]{93}$/;
|
|
| 58 | + if (moneroAddr.test(s)) {
|
|
| 59 | + return true;
|
|
| 60 | + }
|
|
| 61 | + |
|
| 62 | + return false;
|
|
| 63 | +}
|
|
| 64 | + |
|
| 27 | 65 | export class CryptoSafetyParent extends JSWindowActorParent {
|
| 28 | 66 | async receiveMessage(aMessage) {
|
| 29 | 67 | if (
|
| ... | ... | @@ -33,7 +71,24 @@ export class CryptoSafetyParent extends JSWindowActorParent { |
| 33 | 71 | return;
|
| 34 | 72 | }
|
| 35 | 73 | |
| 36 | - let address = aMessage.data.selection;
|
|
| 74 | + // Read the global clipboard. We assume the contents come from the HTTP
|
|
| 75 | + // page specified in `aMessage.data.host`.
|
|
| 76 | + const trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(
|
|
| 77 | + Ci.nsITransferable
|
|
| 78 | + );
|
|
| 79 | + trans.init(null);
|
|
| 80 | + trans.addDataFlavor("text/plain");
|
|
| 81 | + Services.clipboard.getData(trans, Ci.nsIClipboard.kGlobalClipboard);
|
|
| 82 | + let data = {};
|
|
| 83 | + trans.getTransferData("text/plain", data);
|
|
| 84 | + data = data?.value.QueryInterface(Ci.nsISupportsString).data;
|
|
| 85 | + |
|
| 86 | + let address = data?.replace(/\s+/g, "");
|
|
| 87 | + |
|
| 88 | + if (!address || !looksLikeCryptoAddress(address)) {
|
|
| 89 | + return;
|
|
| 90 | + }
|
|
| 91 | + |
|
| 37 | 92 | if (address.length > 32) {
|
| 38 | 93 | address = `${address.substring(0, 32)}…`;
|
| 39 | 94 | }
|