Unveiling BigSpender: Double (and Multiple) Spend Vulnerability in Major Bitcoin Wallets

Imagine receiving a $100 bank wire for some goods or services you just sold. You supply the goods or services as you think you’ve received the money. After all, it shows in your account! 

Except it doesn’t. It’s just an illusion. The attacker was able to cancel the transaction in a way your bank had failed to detect.

Making things even worse, the attacker can repeat this trick 100 times by repeatedly sending and then secretly canceling $100 wire transfers (with the same $100 bill) to create the illusion of sending $10,000.

Adding insult to injury, you discover you can’t spend the money you had before these fraudulent transactions occurred as the transactions corrupted your account. 

This is what the BigSpender attack enables. It allows an attacker to cancel a Bitcoin transaction but still have it appear in a victim’s vulnerable wallet and the cost to execute it is fairly low.

Today we disclose the “BigSpender” vulnerabilities family. These are a set of vulnerabilities in popular Bitcoin wallets, including Ledger Live, BRD wallet and Edge wallet that may expose users to double and multiple spend attacks (hence “BigSpender”), and potentially prevent them from spending their balance.

We suggest some practical measures for users to protect themselves against BigSpender attacks and release a free open source tool to allow wallet providers to test and secure their products. 

Background

As part of our on-going security research in the field of Bitcoin wallets, we investigated the handling of Bitcoin’s Replace-by-Fee (RBF) feature among different existing wallets. In short, RBF is a standard method to allow users to “undo” a yet to be confirmed transaction, by sending another transaction spending the same coins (but possibly different destination) with a higher fee. Unfortunately, as we show in this post, some wallets do not handle such scenarios well.

We responsibly disclosed this vulnerability (CVE-2020-12119) to the vulnerable vendors, but only some fixed it (see full table below). As the customary 90 days disclosure deadline expired on July 1st, we are releasing the details now.

Double-spend and RBF in a nutshell

Double-spending is the result of successfully spending the same money more than once. Preventing it is one of the most critical tasks of any digital cash system.

Paraphrasing from the Bitcoin wiki: in Bitcoin’s blockchain system, everything (the mining, proof of work, difficulty, etc.) is there to produce a history of transactions that is computationally infeasible to modify, thereby making base layer transactions irreversible.

To protect against double-spending, Bitcoin users wait for confirmations when receiving payments on the blockchain. Confirmations happen whenever a block is mined, typically every 10 minutes. Before the first confirmation (sometimes referred to as “zero-confirmations” or “0 conf”), there is no guarantee the transaction will not be double-spent. There might be good reasons for a transaction to be changed, mainly to add more fees to a “stuck” transaction that could otherwise remain stuck for days.

The RBF (replace-by-fee) mechanism was suggested to standardize Bitcoin nodes’ behavior when replacing a “0-conf” transaction with a new one. 

RBF is a relay policy of Bitcoin nodes where a transaction can signal that it may be replaced by a subsequent transaction spending one or more of the same coins by providing a higher fee. That way, a transaction that effectively double-spends an already used coin in another yet to be confirmed transaction can be accepted and relayed in the network.  

This feature was implemented in Bitcoin Core on version 0.12, which dates back to 3 years ago. It does not introduce any new vulnerabilities in itself, as the zero-confirmation double-spending issue is as old as Bitcoin. Instead, it explicitly puts the responsibility on wallet applications and users’ to identify unconfirmed transactions as unsafe.

We recently discovered that several popular wallets have failed to own that responsibility. We call the vulnerability BigSpender, and below, we present its implications.

The BigSpender vulnerability

The core issue at the heart of the BigSpender vulnerability is that vulnerable wallets are not prepared for the option that a transaction might be canceled and implicitly assume it will get confirmed eventually. 

This negligence has many faces. First and foremost, a user’s balance is increased on an incoming transaction while unconfirmed and is not decreased if the transaction is double-spent and thus effectively canceled.

Additional implications include:

  • The state of canceled transactions’ is not updated to “Cancelled” in the users’ transaction history.
  • Canceled transactions’ coins (UTXOs) are still selected by the wallet’s software when constructing transactions.

Additionally, in some wallets, the graphical representation of an unconfirmed transaction in the wallets user interface is not well distinguished from a confirmed state, making it even harder for users to understand these transactions are not final yet.

How attackers can abuse wallets with BigSpender 

Classical “double-spend” attacks are usually complex and probabilistic in nature, putting the attacker at risk of losing their money. However, due to the RBF feature’s standard nature, attackers can easily and with minimal risk launch the following BigSpender exploits: 

  1. Basic double-spend: Attackers can exploit this problem by sending a victim a transaction of some value but with minimum fees (will be pending for a long time) and asking for some goods or services in return, then cancel the transaction immediately. Since the vulnerable wallets do not reflect cancellations and still show an incorrect balance, the victim will see their wallet’s balance has increased and understandably believe the transaction to be complete. As a result, the victim may provide the attacker with the goods or services without receiving any payment.   
  1. Amplification attack: The aforementioned basic attack can be further amplified by repeatedly performing the basic attack. A series of such replaceable transactions can be created to artificially inflate a victim’s balance and expand the attack. For example, attackers with only $10 in their possession can increase a balance by $1K by sending a series of 100 transactions of $10, each canceling the prior transaction.
  1. Denial-of-Service (DoS): Even if wallet owners are not fooled by this attack and do not give any goods in return for the money allegedly sent to them, they are still vulnerable to a denial-of-service attack. Because the vulnerable wallet had miss-calculated the balance, when users try to “send all” their holdings, the transaction fails. Besides the “send all” scenario that will always fail, a victim’s transaction will also fail whenever their wallet’s coin selection algorithm chooses funds from this nonexistent transaction.
BigSpender overview

In some of the vulnerable wallets, this attack is hard (or even impossible) to recover from. Even reinstalling the wallet does not cause it to re-synchronize with the Bitcoin network and show the right balance. If no recovery is possible, the denial-of-service attack becomes permanent.

As a result, attackers can do a mass “BigSpender” DoS by sending a small amount to many users of a vulnerable wallet and canceling it. The consent of victims is not required, and victims are now (entirely or partially) unable to use their funds. Once more, the attacker does not need a big sum of money to launch this attack, as they only pay for the relatively small cancellation fees. 

Vendor findings and responses 

The following table summarizes our findings and the state of vendor fixes for the three vulnerable wallets.

  • BRD Wallet: Vulnerability is fixed on version 4.3 for iOS and Android. We were awarded a bug bounty.
  • Ledger Live: Vulnerability is fixed on version 2.7.0. We were awarded a bug bounty.
  • Edge: Acknowledged the vulnerability, but did not fix it. Plan to fix it in the future.
WalletBasic double spendAmplified spendDoSDoS recovery
(at vulnerable version)
Found in versionFixed in version
BRD walletVulnerableVulnerableVulnerable*Restore seed on another app that supports BRD non-standard derivation path4.2.44.3.1
Ledger LiveVulnerableVulnerableVulnerableClear caches2.0.12.7.0
Edge walletVulnerableNot vulnerableVulnerableResync1.15.1Not fixed
Summary table of findings per vendor

* prevents spending any amount of the wallet if the canceled UTXO is the largest in the wallet. 

Bread Wallet

The wallet was exposed to the basic double-spend attack, as the balance is increased with any unconfirmed incoming transaction but not decreased when a transaction is double-spent.

BigSpender Double-spend on BRD

This also made it susceptible to the amplified spend attack.

Bread wallet Bitcoin screen showing a wrong total balance: all 6 transactions have been replaced and are actually spending
the same coin.

Bread was also exposed to denial-of-service attacks: a receiver of a double-spend transaction would be unable to send the maximum amount in the sending screen. Here, things got even more severe. Bread was apparently selecting UTXOs by picking the largest UTXOs first, with the reverted UTXOs (from the double-spent transactions) included. So when a user sends an amount that would consist of such UTXO, the transfer would fail. For instance, if the reverted output is the largest in the wallet, a send attempt of any amount will fail.

BigSpender Denial of Service attack on BRD

Recovery from this situation would actually be very hard. A fresh install on a new device would run into the same inability to send

Failed recovery of BRD after a BigSpender Denial of Service attack

This leaves the user with the option to migrate its seed from Bread to another wallet. Given that Bread has a non-standard derivation path of key pairs from a seed, this is probably not easy, requiring some expertise from a user and possibly external tools.

Ledger Live

The Hardware wallet desktop client increased the balance on every incoming (unconfirmed) transaction. Jumping right into the amplified double-spend attack: we demonstrate an attacker inflating the victim’s balance to 0.0074 BTC, by re-spending the same 0.0001 BTC coin over and over again (each transaction replacing the previous one by offering a higher fee), until eventually, the attacker sends the last transaction in this sequence of transactions back to themself.

BigSpender Amplified Double Spend attack on Ledger Live

This naturally also caused denial-of-service in the form of preventing a user from being able to spend the maximum balance of their Bitcoin wallet. The issue was resolved by clearing the cache and forcing a network resynchronization. 

Edge 

The issue with Edge wallet was more subtle as the balance was increased only once for a series of pending transactions. The incorrect balance and the inability to send all the wallet’s balance were resolved by clicking “Resync” on the wallet options.

Protections and mitigations

Users should choose a safe wallet that handles RBF transactions correctly. If they decide to use a vulnerable wallet, users must verify that a transaction is confirmed before handing out any goods or services in return. In the case of a BigSpender denial-of-service attack, users can use the recommended method of recovery in the table above.

Wallet developers must test their wallet behavior with respect to RBF transactions and cancellations. 

ZenGo’s solution to BigSpender

Expected wallet behavior, such as the one implemented in the ZenGo wallet, would clearly show pending transactions and not add them to users’ balance before they are confirmed. If a transaction gets canceled, it should be clearly reflected in users’ transaction history.

To help developers implement this solution on other wallets, we’re publicly sharing our research tool: https://github.com/KZen-networks/big-spender.

We propose the following steps to handle double-spent transactions in a wallet application:
1. Do not increase the balance before a transaction is confirmed.

2. Make a clear distinction between “pending” and “confirmed” states of a transaction.

3. Detect when a transaction is double-spent and mark a double-spent transaction as “failed”.

Conclusion

Simplicity is a critical element in making cryptocurrency more accessible to the masses. However there is a difference between simplifying, and over-simplifying. Einstein once said, “Everything should be made as simple as possible, but no simpler.” 

In this case, Bitcoin’s confirmation procedure was over-simplified, at the expense of users’ security. At ZenGo, we believe that user security and simplicity are not contradictory. When thought together they can bring superior user experiences and safety. We strive to keep it as simple as possible, but never simpler than that. 

Update

Since its release, BigSpender was covered by leading Crypto and Tech media. Read more about BigSpender and the affected wallets’ responses below: