Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix BSQ swap buyer tx fee theft vulnerability #5889

Merged

Conversation

stejbac
Copy link
Contributor

@stejbac stejbac commented Dec 2, 2021

Prevent the seller from stealing the combined tx fee as change by lying about the value of one or more of his BTC inputs, which are passed to the buyer as raw inputs in the BsqSwapFinalizeTxRequest message.

To this end, add a RawTransactionInput::validate method to check the value field against the output value of the respective spending tx and run it on every raw seller input in ProcessBsqSwapFinalizeTxRequest, so that the buyer is no longer just trusting those numbers.

Additionally, check that the spending txIds from the raw BTC inputs supplied by the seller actually match those of his signed inputs in the accompanying partially signed tx, thus tying the raw input values to the seller's tx.

--

This should block an attack by the BTC seller that I was able to carry out on regtest. If the seller is the taker, the attack can be made worse by creating a swap trade with the tx fee set at just under twice that seen by the maker, so that it is still within tolerance. So the seller-as-taker could wait until the tx fee spikes to, say, 50 sat/vbyte (but the mempool is not too full) and then take an offer with the tx fee set to 99 sat/vbyte. In this way, they could steal around 12000 sat or so as change and still leave 1 sat/vbyte for the fee so that the transaction eventually confirms. The attack is made worse the more inputs the maker uses or the higher the broadcast tx fee.

(Actual tolerance by maker of agreed tx fee is 50%, not 10%.)
Prevent the seller from stealing the combined tx fee as change by lying
about the value of one or more of his BTC inputs, which are passed to
the buyer as raw inputs in the 'BsqSwapFinalizeTxRequest' message.

To this end, add a 'RawTransactionInput::validate' method to check the
'value' field against the output value of the respective spending tx and
run it on every seller input in 'ProcessBsqSwapFinalizeTxRequest', so
that the buyer is no longer just trusting those numbers.

Additionally, check that the spending txIds from the raw BTC inputs
supplied by the seller actually match those of his signed inputs in the
accompanying partially signed tx, thus tying the raw input values to the
seller's tx.
Add a check of 'scriptTypeId' field, against the output of the spending
tx, to the 'RawTransactionInput::validate' method. Also make the seller
as well as the buyer validate each raw BSQ/BTC input received from the
peer. This prevents either peer from claiming that any of their
non-segwit inputs are segwit in order to underpay the tx fee.
@ripcurlx ripcurlx added this to the v1.8.0 milestone Dec 3, 2021
Copy link
Contributor

@chimp1984 chimp1984 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK

Copy link
Contributor

@ripcurlx ripcurlx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK - based on #5889 (review)

@ripcurlx ripcurlx merged commit 628ac27 into bisq-network:master Dec 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants