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

psbt: restore compatibility with wallets that patch CVE-2020-14199 #178

Merged
merged 4 commits into from
Aug 26, 2020

Conversation

guggero
Copy link
Contributor

@guggero guggero commented Jul 20, 2020

Fixes lightningnetwork/lnd#4400.

Wallets that include the fix for the CVE-2020-14199 vulnerability always include the full non-witness UTXO even if the output being spent is a witness output.
To restore compatibility with those wallets, Bitcoin Core removed the sanity checks on partial inputs.
This PR does the same for the btcutil/psbt library.

As described in CVE-2020-14199 it is unsafe to only rely on witness
UTXO information when signing. Hardware wallets fixed this by also
requiring the full non-witness UTXO to be present for a witness input.
To be compatible with those newer hardware wallet firmware, we need to
remove the sanity checks that disallowed setting witness and non-witness
UTXOs at the same time.
See bitcoin/bitcoin#19215 for comparison which
removed the sanity checks in Bitcoin Core.
As a countermeasure to CVE-2020-14199 new HW wallet firmwares require
the full non-witness UTXO to be set even for witness inputs.
We therefore shouldn't remove it when signing.
A wallet that has patched the CVE-2020-14199 vulnerability will always
include a non-witness UTXO, even for witness inputs. In the signer, we
detect that the input we spend is a witness input and copy over the
TxOut to the witness UTXO field. Therefore it is possible that both UTXO
fields are set at the same time. We need to adjust the sanity checks
when adding a partial signature to account for that.
We add a test that makes sure the full signing scenario of a wallet that
has the CVE-2020-14199 vulnerability patched is supported by this
library.
@Roasbeef
Copy link
Member

cc @halseth

@@ -102,6 +102,11 @@ func (p *Updater) addPartialSignature(inIndex int, sig []byte,
}
}

// Attaching signature without utxo field is not allowed.
Copy link
Member

Choose a reason for hiding this comment

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

So this now forces all implementations to implement the check? I guess from a conservative PoV, this is the safest thing to do. However IMO, the bug itself was a bit overblown, in that it requires the user to sign multiple times (it's a fault attack essentially), and hardware wallets generally don't keep any state between signing attempts.

Zooming out, does this mean that in order to implement the generic PSBT calls in the lnd side, we now require a txindex for the target backend? Also this means that nodes using the neutrino backend wouldn't be able to use it as it (this library at the very least) can't populate this data?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is just the else case that was moved up. We even loosen some restrictions by allowing both UTXO fields to be set and checking both.

I also think the bug was overblown a bit. But I can see why a bug "that can cause you to lose money" sounds very bad for a HW wallet manufacturer.
But because most HW wallets are now patched, we need to at least be compatible with their PSBT packets and not reject them.

I don't think this change forces chain backends to enable the txindex. Because as an updater you only need to know about the UTXOs involved. And because wallets keep the full transaction records for UTXOs in a separate DB anyway (or at least btcwallet does), no TX lookup should be necessary.

We use the Wallet.FetchInputInfo to add the UTXO information which uses UnstableAPI(w).TxDetails(txid). From what I can see this only does DB lookups and no queries to the backend.

Copy link
Contributor

@halseth halseth left a comment

Choose a reason for hiding this comment

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

I don't have much context from this code previously, so take this ACK from me lightly.

@guggero guggero requested a review from Roasbeef August 25, 2020 18:20
Copy link
Member

@Roasbeef Roasbeef left a comment

Choose a reason for hiding this comment

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

LGTM 🥩

@Roasbeef Roasbeef merged commit 5f93e33 into btcsuite:master Aug 26, 2020
@guggero guggero deleted the psbt-vuln-fix branch August 26, 2020 19:49
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.

PSBT Funding flow retry, instructions for converting binary PSBT to base64, and accept PSBT from file,
3 participants