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

rpc: verify address is for correct net #6448

Conversation

torkelrogstad
Copy link
Contributor

@torkelrogstad torkelrogstad commented Apr 23, 2022

Change Description

Verify that the addresses we're decoding when sending coins onchain are
for the correct network. Without this check we'll convert the users
addresses to their equivalent on other networks, which is a gross
violation of the principle of least astonishment.

Steps to Test

Prior to this commit:

  1. Run a node on regtest
  2. Issue either a sendmany or sendcoins RPC, with a mainnet or testnet address
  3. Observe that the address is accepted, and converted into a regtest address.

After this commit, step 2 fails.

Pull Request Checklist

Testing

  • Your PR passes all CI checks.
  • Tests covering the positive and negative (error paths) are included.
  • Bug fixes contain tests triggering the bug to prevent regressions.
    There doesn't seem to be any tests for this, at least not based on a quick code search. Would be happy to implement if I'm wrong.

Code Style and Documentation

📝 Please see our Contribution Guidelines for further guidance.

Verify that the addresses we're decoding when sending coins onchain are
for the correct network. Without this check we'll convert the users
addresses to their equivalent on other networks, which is a gross
violation of the principle of least astonishment.
Copy link
Collaborator

@guggero guggero left a comment

Choose a reason for hiding this comment

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

Thanks for the fix! LGTM 🎉

Copy link
Collaborator

@guggero guggero left a comment

Choose a reason for hiding this comment

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

Actually, while we're at it, we should probably also add the check here:

Or, to fix the underlying assumption that (because it takes the net params as the second parameter) DecodeAddress actually checks that the address belongs to the correct network, we should perhaps add the check there?
Looking at the code, this seems to only be possible with non-Segwit (non-bech32) addresses in the first place.

@torkelrogstad
Copy link
Contributor Author

Or, to fix the underlying assumption that (because it takes the net params as the second parameter) DecodeAddress actually checks that the address belongs to the correct network, we should perhaps add the check there?

Do you mean changing btcutil? That sounds like a pretty big behavioral change in how DecodeAddress works

@guggero
Copy link
Collaborator

guggero commented Apr 23, 2022

Do you mean changing btcutil? That sounds like a pretty big behavioral change in how DecodeAddress works

Yes, maybe it's too big of a change. But maybe it would be worth adding a comment in the btcutil library that for legacy addresses the network isn't checked.

@torkelrogstad
Copy link
Contributor Author

Found another place, in chancloser

// ParseUpfrontShutdownAddress attempts to parse an upfront shutdown address.
// If the address is empty, it returns nil. If it successfully decoded the
// address, it returns a script that pays out to the address.
func ParseUpfrontShutdownAddress(address string,
params *chaincfg.Params) (lnwire.DeliveryAddress, error) {
if len(address) == 0 {
return nil, nil
}
addr, err := btcutil.DecodeAddress(
address, params,
)
if err != nil {
return nil, fmt.Errorf("invalid address: %v", err)
}
return txscript.PayToAddrScript(addr)
}

For the sake of returning errors that look the same in all places, and ergonomics, would it be an idea to introduce a new wallet in btcutil? Filed an issue in btcd, figured that was a better place to discuss: btcsuite/btcd#1846

@guggero
Copy link
Collaborator

guggero commented Apr 25, 2022

Looking at the code, this seems to only be possible with non-Segwit (non-bech32) addresses in the first place.

Oops, I was wrong there. I read the if chaincfg.IsBech32SegwitPrefix(prefix) { incorrectly. It doesn't check that the prefix is for the given network, it just checks if it's any valid prefix...

I like your idea of adding DecodeAddressForNet in btcd. Since we'll be bumping the dependency to that project anyway, I'd rather use that method everywhere in lnd (after the PR there was merged) than add the IsForNet check everywhere.

@Roasbeef Roasbeef requested a review from arshbot May 4, 2022 22:38
Copy link
Contributor

@arshbot arshbot left a comment

Choose a reason for hiding this comment

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

tACK on the bug to be fixed, agree with all that the fix should be included in DecodeAddressForNet, that way it can trickle into other projects.

Friend at mitbitcoin actually ran into this same issue, so there is real need for this fix.

@Roasbeef Roasbeef modified the milestones: v0.15.0, v0.15.1 May 10, 2022
@Roasbeef Roasbeef modified the milestones: v0.15.1, v0.16.0 Jul 27, 2022
@Roasbeef Roasbeef modified the milestones: v0.16.0, v0.17.0 Aug 23, 2022
@lightninglabs-deploy
Copy link

@torkelrogstad, remember to re-request review from reviewers when ready

@guggero
Copy link
Collaborator

guggero commented May 12, 2023

Replaced by/included in #7689, original commit author credits are preserved.

@guggero guggero closed this May 12, 2023
@saubyk saubyk removed this from the v0.18.0 milestone Aug 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants