5

Let's imagine, an attacker managed to corrupt your local list of unspent transaction outputs (or a blockhain explorer you use) in a way that certain unspent transaction outputs seem to hold less coins than actually. When you proceed to make a new transaction to send 1 BTC and load your list of unspent outputs, you happily take as an input an output that seemingly has 2BTC but actually it has 100 BTC, but you don't know it since you have fake information. Therefore you set your transaction outputs to be 1 BTC for the receiver and 0.99 BTC as change, believing to pay a fee of 0.01 BTC and you happily sign and submit that transaction. But to your big dissapointment, you find out the next day that you actually paid/lost 98 BTC as a fee! The attacker did not gain anything, but he made you lose a significant amount of BTC.

My point is that the transaction inputs in the serialized transaction cointain only the output index and hash of the transaction where the output comes from. But since you do not broadcast to the network, which size you believe the input to be - you can sign and submit a valid transaction despite not agreeing with it, had you known the actual size of the inputs involved.

I know - you can verify the hashes of the transactions where the inputs come from and if something seems off, reject the transaction, or the transaction will be rejected by the network, since it is not practically achievable to "crack" the transaction hashes, but I'm not sure if lightweight clients/hardware wallets actually verify the origin of unspent outputs and I have a suspicion that TREZOR, for example, does not do it, since in the protocol you just send the transaction inputs and outputs.

So can you tell me, how and if current lightweight clients and hardware wallets are protected against the attack described above?

A simple fix to the issue above would be including the amounts explicitly in the transaction inputs, so when you sign the transaction you say "I believe that input x has y coins and reject the transaction if you think this is not true", but currently there is no way to do this AFAIK.

3

Therefore you set your transaction outputs to be 1 BTC for the receiver and 0.99 BTC as change, believing to pay a fee of 0.01 BTC and you happily sign and submit that transaction. But to your big dissapointment, you find out the next day that you actually paid/lost 98 BTC as a fee! The attacker did not gain anything, but he made you lose a significant amount of BTC.

Indeed, this would work, and it is a known issue.

I know - you can verify the hashes of the transactions where the inputs come from and if something seems off, reject the transaction, or the transaction will be rejected by the network, since it is not practically achievable to "crack" the transaction hashes, but I'm not sure if lightweight clients/hardware wallets actually verify the origin of unspent outputs and I have a suspicion that TREZOR, for example, does not do it, since in the protocol you just send the transaction inputs and outputs.

Actually, they do verify this. For legacy transactions, you have to send the TREZOR all transactions whose outputs you are spending from, to prove the amounts involved.

A simple fix to the issue above would be including the amounts explicitly in the transaction inputs, so when you sign the transaction you say "I believe that input x has y coins and reject the transaction if you think this is not true", but currently there is no way to do this AFAIK.

That is indeed a solution, and that is one of the changes that were included in the SegWit protocol change. When spending a SegWit output, a new way to compute signature hashes is used, which explicitly includes the amount you're spending.

This means that if you would somehow lie to the hardware device about the amount being spent, the resulting signature would be invalid.

You can read more about this change in BIP 143.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.