Instead of holding your bitcoins with a single set of keys, you can also hold your bitcoins with several sets of keys. This is known as multisignature, or multisig for short, which requires multiple signatures to authorize a Bitcoin transaction. You can determine both the overall number of keys and the threshold required to spend the coins. If you choose a threshold bigger than one, an attacker who learns one of the keys can still not steal your funds. This is why many people in the field recommend that everyone should use multisig to secure their coins. However, this article explains why the increased complexity of using multisig instead of singlesig has its own pitfalls. Included are responsible disclosures we made to SatoshiLabs (producing Trezor) and Ledger in this regard, which we haven’t published before.
Why are we investigating our competitors?
When implementing experimental support for multisig in the BitBoxApp, I made my colleague benma aware that the receive address screen of his Trezor cannot be trusted in case of multisig (see below for more details). After realizing how important it is to handle change addresses similarly to receive addresses earlier this year, we were getting more curious about how other hardware wallets handle multisig. We launched the BitBox02 at the end of September and finally had some time to look at other hardware wallet implementations, also in order to evaluate how much effort is required to properly add multisig ourselves. We stumbled over several issues, which resulted in responsible disclosures to Trezor, Coldcard and Ledger (as discussed here).
Why should I use a hardware wallet?
I went into more details in a previous blog post, but in short, a hardware wallet should allow you to securely receive and spend funds, as well as securely receive the change back to the same account, even when your computer or mobile phone has malware. While each manufacturer can define what their product does and does not protect you against, we think that the threat model for hardware wallets should include malicious or compromised cosigners in case of multisig. The reason for this is that companies are interested in using multisig as part of coin storage, rate-limiting, or inheritance services. If their infrastructure gets compromised, a lot of users could be affected — especially if they use the service provider’s app to interact with their hardware wallet.
What is the motivation for using multisig?
There are two main use cases for multisig: (i) sharing the authority to spend coins among several parties with no single point of failure or (ii) reducing the impact of vulnerabilities by using hardware wallets from different manufacturers. In both scenarios, you should pay attention to certain things. Otherwise, you might end up with less security than if you were using ordinary singlesig. Multisig adds complexity for the hardware wallet, the software wallet, and for you, but “complexity is the enemy of security”. Moreover, because singlesig is much more popular than multisig, companies pay more attention to the security and usability of their singlesig workflow rather than their multisig implementation. While I agree that multisig is more secure in theory, the following sections outline why this sometimes might not be the case in practice.
How can you back up the multisig setup securely?
The first pitfall occurs before you even start receiving or spending money. Assume you create, for example, a 2 out of 3 setup, where the threshold is smaller than the number of cosigners. In other words, 2 signatures are required out of 3 possible signatures to approve a transaction. It is absolutely crucial that each cosigner’s backup includes the extended public keys (xpubs in short) of all other cosigners (at the multisig account keypath and ideally together with the used threshold, derivation path and script type). Otherwise the loss of a single seed means that you can no longer recover and spend the funds. This is because unspent transaction outputs of multisig accounts are locked with the hash of all public keys (and the threshold). Technically, if you can no longer derive the public keys of all cosigners, you can no longer determine the redeem scripts necessary to find and spend the UTXOs of your multisig account. For example, if you set up a 2 out of 3 multisig account but forget to also back up the extended public keys of the other two cosigners, then two out of three are enough to spend and receive money as long as the individual (hardware) wallets are functional. However, if you all lose access to your wallets for whatever reason, you need all three seed backups instead of just two for recovery.
How can you receive coins securely with multisig?
Your hardware wallet should verify, or let you verify, the following information provided by the untrusted computer:
- The receive address, which has to encode the hash of an ordinary multisig redeem script with no other spending conditions
- The key of the hardware wallet, which has to be one of the public keys in the redeem script
- The keypath of the displayed address in order to avoid ransom attacks if no restrictions are enforced by the hardware wallet
- The number of cosigners in order to prevent an attacker from adding more
- The threshold of required signatures to not be higher or lower than intended
- The xpubs of the cosigners in order to prevent an attacker from swapping them
In order to avoid a single point of human failure when using a receive address, the same threshold of cosigners should confirm to the sender that the receive address has been transmitted correctly. If you are using a multisig setup in order to avoid the risk of a vulnerability in the firmware of a particular device, you should check the receive address on multiple hardware wallets. Receiving coins securely is just as important as spending coins securely.
So how do different hardware wallets handle this?
As others have noticed before, Ledger does not handle this. Instead, the user needs to trust the receive address that is displayed on the computer, contrary to the purpose of a hardware wallet.
Trezor verifies that its key is part of the properly formed receive address and displays to the user all other information (see once more the above tweet on Ledger) except the cosigners. For simplicity, manufacturers try to keep the firmware of hardware wallets as stateless as possible and consequently try to avoid storing anything but the seed. Until the firmware version 2.1.8 was released on 6 November 2019, there was no way for the user to verify the xpubs of the cosigners provided by the computer. In other words, malware could replace the xpubs of the two cosigners in our 2 out of 3 multisig example above, and the attacker would then fully control the received coins. This is a real problem as users are educated to trust the screen of their hardware wallet but are not educated about the above replacement risk that makes the device screen untrustworthy in case of multisig. This is the second vulnerability we disclosed to Trezor and it is mentioned in the release notes. They considered it to be more of a usability problem rather than a security one. (As long as you check the receive address on multiple devices that each confirms its key is included in the multisig address, this would indeed not be a security issue.) While the new firmware still does not persist your multisig configuration, you can now verify the xpubs of your cosigners when displaying a multisig receive address:
Inconveniently, as far as we can tell, the Trezor does not indicate which xpub is yours. Since the hardware wallet provides your own xpub, you wouldn’t have to verify it yourself. On the other hand, as there seems to be no other method to display your own xpub on the trusted screen of your Trezor, at least you can now tell your cosigners with more confidence what your own xpub is.
Coldcard has the best approach by persisting the multisig configuration after an initial setup. However, it had a problem with the sanitization of the derivation keypath, which we responsibly disclosed to them.
How can you spend coins securely with multisig?
Once you managed to receive some coins securely, how can you spend them with confidence? The hardware wallet has to verify, or let you verify, the following information provided by the untrusted computer:
- The recipient’s address, displayed and confirmed by the user like with singlesig
- The change address, having the same cosigners and threshold in an ordinary multisig script with no other spending conditions
- The change goes to an address at a keypath recoverable by the user
So how do different hardware wallets handle this?
By checking the multisig configuration, Coldcard has the best approach. However, by not enforcing enough restrictions on the keypath, the change is not ensured to be accessible. We responsibly disclosed this issue, and it was fixed in the firmware 3.0.2 released on 1 November 2019.
Trezor verifies that the change goes back to the same wallet account (with the same cosigners and threshold) but had a mistake in its verification. Because Trezor did not properly separate the singlesig and multisig workflows, an attacker could (i) add a shared multisig input to a singlesig transaction, then (ii) send the change to the same multisig account and (iii) steal all the user’s funds from there. We reported this critical remote attack on 1 October 2019, which was fixed in the firmware version 2.1.8 released on 6 November 2019. (See this writeup by benma for more information.) Other than that, their approach to neither persist, nor let the user confirm, the xpubs of the cosigners works for spending because the redeem script with the public keys of the cosigners is part of the hash that is being signed. Consequently, if malware on your computer lies about the xpubs of your cosigners when signing a transaction, other nodes in the Bitcoin network would reject the invalid transaction.
As Saleem Rashid already pointed out almost two years ago, Ledger leaves the change output for the user to confirm in case of multisig transactions, which leads to various problems. How are users supposed to verify the change address? If they need a separate, fully trustworthy computer for this, why would they need a hardware wallet in the first place? If we assume that the user must confirm the change address with the cosigner, then this leads to the following two issues:
- Send-to-many not clearly distinguishable from multisig: The only way users can tell whether they are signing a multisig rather than a send-to-many transaction is that they get a change keypath warning in the former case but not in the latter. Ordinary users cannot be expected to notice the difference and multisig users are familiar with the process of always confirming something more than the intended recipient on a Ledger. Hence a compromised cosigner can provide a send-to address that they alone control and have it be mistakenly confirmed as a multisig “change” address.
- Reducing the multisig threshold: If you have an M out of N multisig setup, you cannot detect when the multisig threshold of the change output is lowered to 1 out of N. In case a compromised cosigner lies to you about what is the change to be confirmed, they can steal the change after the transaction is completed.
While these two problems are solved if users have access to a change oracle that tells them what the change has to look like, there is another issue users cannot protect against:
- Singlesig inputs to multisig change: If the user also holds singlesig funds on the same Ledger, an attacker can fund a multisig transaction that the user wants to perform with their singlesig UTXOs instead of taking them from the multisig account. If the multisig account has a 1 out of N configuration, a malicious or compromised cosigner can spend the change immediately afterwards. In other words, due to this design choice, a Ledger does not verify that the change goes back to the same account, which puts your singlesig (and other multisig) funds at risk.
Please note that these attacks require that the victim’s computer is compromised, which is a common assumption for the threat model of hardware wallets. We reported all three issues to Ledger on 4 November 2019. They responded that this is all expected behavior, and that they are working on a new Bitcoin application that should address these issues (see this comment on Reddit for more information). If you do use your Ledger both for singlesig and multisig and wouldn’t trust your cosigners with your singlesig funds, we recommend to first move your singlesig funds to a different wallet before you sign further multisig transactions. Moreover, we recommend to use a single Trezor or Ledger device for at most one multisig setup because you cannot know from which account you are spending as the account is not displayed.
What do all attacks have in common?
The source of all vulnerabilities mentioned here is that the hardware wallets either try to be smart and display as little as possible (Trezor and Coldcard) or try to be dumb and display more (Ledger), but both approaches failed, i.e. they neither verified enough nor displayed enough. Striking a balance between the two with the right amount of silent verification and user confirmation is not easy. Moreover, it seems to me that this family of “change the change” attacks needs closer attention. All of the attacks mentioned in this article were (or still are) remote attacks, where a compromised computer can simply misuse the API of the hardware wallet. For ideas about what hardware wallets could do to mitigate such attacks and therefore improve their security, check out benma’s article. And while this article focuses on hardware wallets, it’s important to note that with the use of multisig, software wallets are vulnerable to API misuse attacks too as transactions can be passed to them similar to hardware wallets.
Credits go to TheCharlatan for figuring out that you can send singlesig funds to multisig change with a Ledger and to benma for questioning the assumption that cosigners are trustworthy, while I refined the above attacks and reported them to Ledger. TheCharlatan also took care of replicating them with changes to the Electrum wallet and HWI. This concludes our vulnerability disclosure trilogy.