ma1 pushed to branch tor-browser-128.2.0esr-14.0-1 at The Tor Project / Applications / Tor Browser

Commits:

2 changed files:

Changes:

  • browser/actors/CryptoSafetyChild.sys.mjs
    ... ... @@ -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
         });
    

  • browser/actors/CryptoSafetyParent.sys.mjs
    ... ... @@ -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
         }