It is possible to make a valid PSBT file that sends the change left from a transaction to a unknown location. If an attacker had your XPUB, and could change your PSBT file before you sign, they could modify the file so that the “change” (ie. the balance of Bitcoins you are sending back to yourself) goes to an effectively unknown address. If the attacker is profit motivated, they can ransom the knowledge of those change UTXO back to you.
For example, the original PSBT might have intended to send the
change for the transaction to
m/44'/1'/0'/1/4 but because of the
attacker, it gets sent to
Your Coldcard has the private key for that address, and can get it back,
but if you don’t know that path, it may not be
practical to search for it on the blockchain.
From the start, there are few things that limit the effectiveness of this attack:
The attacker must know your XPUB. Without the XPUB, it’s not possible to calculate the public key values needed both on the input and output sides of the PSBT. Although it is possible to include the XPUB in the PSBT file, we do not recommend that, and do not know of any wallet doing so, at this time.
If you kept your (modified) PSBT file, it would be trivial to detect and undo the effects of the attack. This happens by default when using MicroSD cards for transport (sneakernet FtW again).
MiTM (man in the middle) access is required to your PSBT files. This means a compromised desktop is required, and the attack can only occur when you initiate a spend. Because the USB protocol with Coldcard is end-to-end encrypted, a USB interception cannot be used to modify data in-flight.
A limitation of the current PSBT standard (BIP174) is that it does not include any signatures, or other means to verify the file contents, but none the less, we can detect and block this attack. Version 3.0.2 of our firmware is very effective at stoping this type of attack.
The Coldcard already had robust “change fraud” detection, which checks for easier (non XPUB-aware) hacks to the PSBT, such as just simply sending change to an attacker-controlled address (which isn’t what’s happening here). In those cases, it will stop the transaction and declare (on the screen) that “Change Fraud” has occurred.
Those checks have now been expanded so that Coldcard will also check that the subkey derivation paths provided in the PSBT meet a very rigid and conservative set of rules. In this process, we are making many assumptions about how the wallet that generated the PSBT works, so there may be false positives. For this reason, we are treating strange change paths as “warnings” for now. In time, we may change them to be fatal errors.
As of version 3.0.2, the Coldcard will analyze paths used for change outputs and show a warning if they are not similar in structure to the inputs of that same transaction in the PSBT file.
These are imperfect heuristics and if you receive a false positive, or are doing weird things that don’t suit the rules below, please send an example PSBT to support and we’ll see if we can handle it better.
The Coldcard will check that change outputs match the structure of the input UTXO’s being signed:
- same derivation path length
- shared pattern of hardened/not path components
- 2nd-last position is one or zero (change/not change convention)
- last position within 200 units of highest value observed on inputs
- all derivation paths are now limited depth 12.
If your PSBT file does not match this, you will get a “Troublesome Change Outs” warning during the transaction approval process. The expected and actual values observed will be shown on-screen, and you may approve the transaction if you wish.
Low-Tech / Other Mitigations
It probably makes sense to securely store unsigned and signed PSBT files as part of your transaction processing. Doing that will allow you to undo this effects of this attack easily, and provides useful diagnostic data regardless. Of course, privacy can be impacted based on contents of the old PSBT files.
We cannot recommend storing XPUB values inside PSBT files. It makes this MiTM attack possible, and might allow other privacy-damaging leaks or attacks in the future. Generally, XPUB values should be treated as confidential data.
Thanks to @TheCharlatan for reporting this to us.