Author

Topic: Can Bitcoin scripting used for double spending attacks? (Read 902 times)

donator
Activity: 1218
Merit: 1079
Gerald Davis
Anybody can create a "standard" transaction whose output can be spent by the owner of address X; this transaction is commonly known as "send money to address X". But anybody can also create a transaction whose output can be spent by either the owner of address X or the owner of address Y; this doesn't require any cooperation from the owner of either address, they could even not exist at all and the transaction would still be valid (although unclaimable).

Am I missing something here?!? Huh

Well besides the fact that you keep misusing the term address?  Address =/= PubKeyHash =/= PubKey.  It may seem trivial but it helps if you use the correct term.  It is unclear if you are just using the wrong term lazily or you misunderstand the difference in the terms terms.

You can create an Address which is "locked" by one of two PubKeys (or m of n) using P2SH or you can create an Address which is "locked" by one of two PubKeyHashes (or m of n) using native multisig.   The key point is you aren't making a transaction which spends to one of two addresses.  You are making a transaction which spends to a NEW UNIQUE ADDRESS that is neither x or y from your example.  If that Address isn't in the victim's wallet, they aren't going to even see the transaction (much like they don't get notification of any other transaction to an address that isn't in their wallet).

You could also make up a bogus "normal" (PayToPubKeyHash) Address, send funds to it, and then try to trick the victim into thinking that you paid them.  If your bogus address isn't in their wallet they won't see it.  The only way that is going to happen is by giving the victim a private key, convincing them to import it to their wallet, then pay the victim by sending funds to the address which corresponds to that private key.  The victim will see a payment and then since you know the private key you can spend it before the victim does.  I doubt you consider that much of a security risk.  Multisig doesn't change that dynamic at all.

legendary
Activity: 4536
Merit: 3188
Vile Vixen and Miss Bitcointalk 2021-2023
Why would anyone need to create anything? If I want to make a transaction that allows its output to be spent by either the owner of an address, I don't need his cooperation, I just need to know the destination address, which doesn't even need to be a real address at all. Then, if I want instead to create a transaction whose output can be spent by the owners of one of two addresses... how is this exactly different from above?!? Huh
The address. That is what is exactly different. An output that can be spent by one particular key has one address. An output that can be spent by that key or a different one has an entirely different address. Unless the owner of the wallet specifically created that address, any transaction sent to it will not be recognised, even though the wallet has one of the required keys and could theoretically spend the coins. But it can't spend the coins, nor can it include them in the balance, because it doesn't know it can spend from that address. Only addresses created by the receiver are recognised.
full member
Activity: 168
Merit: 100
Guys, please calm down, I'm just trying to understand  Cheesy

I asked "is it possible to create a transaction that can deceive a walllet into telling its user "I received some BTC!" while instead those BTCs can be spent by someone else?".

You answered "this is not possible because this would require the receiver to create a non-standard and blatantly broken address".

Then I asked "why should anyone create anything? In order to send a payment to somebody, you only need to know the destination address, which doesn't even need to actually exist, as you can blissfully send money to blackhole addresses and nobody is going to complain about this!".

Why would anyone need to create anything? If I want to make a transaction that allows its output to be spent by either the owner of an address, I don't need his cooperation, I just need to know the destination address, which doesn't even need to be a real address at all. Then, if I want instead to create a transaction whose output can be spent by the owners of one of two addresses... how is this exactly different from above?!? Huh

Anybody can create a "standard" transaction whose output can be spent by the owner of address X; this transaction is commonly known as "send money to address X". But anybody can also create a transaction whose output can be spent by either the owner of address X or the owner of address Y; this doesn't require any cooperation from the owner of either address, they could even not exist at all and the transaction would still be valid (although unclaimable).

Am I missing something here?!? Huh
legendary
Activity: 1260
Merit: 1168
This message was too old and has been purged
donator
Activity: 1218
Merit: 1079
Gerald Davis
I was under the assumption that in order to send a payment you only need to know the address you want to send it to

Exactly.  Please send me 1 mBTC.  I am not going to provide you my address but please send me 1 mBTC.  Thank you.
legendary
Activity: 3472
Merit: 4801
The model used in Bitcoin is that the receiver specifies the address they'll accept for a transaction.

Could you please clarify this a little?

I was under the assumption that in order to send a payment you only need to know the address you want to send it to, and no contact with the receiver is needed, ever; the receiver could even be completely offline, as in a paper wallet. What do you mean by "the receiver specifies the address they'll accept for a transaction"?


"you only need to know the address you want to send it to"

And how exactly do you know this address?  It's because the address was specified to you by whomever you are paying.  In other words, it was specified to you by the receiver.
full member
Activity: 168
Merit: 100
The model used in Bitcoin is that the receiver specifies the address they'll accept for a transaction.

You can create a single address which can be spent using 1 of 2 keys however it is the receiver who creates and provides the address.

Could you please clarify this a little?

I was under the assumption that in order to send a payment you only need to know the address you want to send it to, and no contact with the receiver is needed, ever; the receiver could even be completely offline, as in a paper wallet. What do you mean by "the receiver specifies the address they'll accept for a transaction" and "it is the receiver who creates and provides the address"?
donator
Activity: 1218
Merit: 1079
Gerald Davis
That depends on if the wallet you are using has any bugs that fail to deal with non-standard output scripts in a safe manner.

How do they react to non-standard transactions at all? Do they just ignore them? If f.e. a transaction output could be claimed by both address A and address B's private keys (the simplest case), would the wallet containing address B tell its user "I just received 42 BTC"?

There is no such script.  Multisig doesn't work that way.  You can create a single address which can be spent using 1 of 2 keys however it is the receiver who creates and provides the address.  So it would be more like this:
Attacker:  Hey I want to pay you so create a new multisig address, you have to use the RPC commands because it isn't possible from the GUI in the mainline client.  However don't use two pubkeys under your control just for fun lets make the address use one of your pubkeys plus one of mine.  Here it my public key.
User:  Ok that sounds legit.  After a ton of struggling I did it.  Here it the P2SH address. 1xyz
Attacker:  Ok I paid 1xyz.

Does that sound likely?
staff
Activity: 4284
Merit: 8808
No competent wallet software would recognize a payment to an scriptPubKey of a kind they wouldn't have created as theirs, and no wallet programs that I'm aware of do.  The model used in Bitcoin is that the receiver specifies the address they'll accept for a transaction. You can make up random stuff that, in theory, someone else could spend ("It's just one greater than some other private key of yours!", or some script) but they're not going to notice it.

Non-standardness has nothing to do with it— a 1 of 2 multisig is perfectly standard. The reason wallets will not report payments to such a thing is that they didn't author it.   A scriptPubKey _is_ a public key.  Expecting a wallet to magically notice a random unsolicited 1 of 2 scriptpubkey that contains a EC point they happen know the discrete log of is just like expecting them to notice a payment governed by a private key one greater than one that they know.
full member
Activity: 168
Merit: 100
That depends on if the wallet you are using has any bugs that fail to deal with non-standard output scripts in a safe manner.

How do they react to non-standard transactions at all? Do they just ignore them? If f.e. a transaction output could be claimed by both address A and address B's private keys (the simplest case), would the wallet containing address B tell its user "I just received 42 BTC"?
legendary
Activity: 3472
Merit: 4801
However, the question somewhat remains: could a transaction be crafted to fool a wallet into telling its user "I received X BTC" while someone else can actually claim the sum using another private key?

That depends on if the wallet you are using has any bugs that fail to deal with non-standard output scripts in a safe manner.

I'm not aware of any such bugs in Bitcoin Core, Armory, Electrum, or MultiBit.  If you are using some other wallet, you'd have to research how they handle address generation from output scripts and if they have any exploitable flaws.
full member
Activity: 168
Merit: 100
Ok, sorry, I was misled by how sites such as blockchain.info display transactions: a transaction doesn't actually contain any "output address", it only contains outputs which state the conditions necessary to spend them; the "output address" is computed by checking which address's signature is requested by the output script; thus it's impossible to "send money to address B" without actually placing address B in the output script.

However, the question somewhat remains: could a transaction be crafted to fool a wallet into telling its user "I received X BTC" while someone else can actually claim the sum using another private key?
full member
Activity: 168
Merit: 100
There is no sum deposited into an address.

There is only an output encumbered with a requirement that must be met to spend that output.

If the requirement says:
"To spend this output you must supply a valid ECDSA signature from the private key that is associated with address A"

Then as a short hand way of talking about the transfer of control of value, we humans say:
"The bitcoins were sent to address A"

Notice, there are no bitcoins, there is no actual sending, and there is no deposit.  There is only an output and a requirement.  Everything else is an abstraction that we humans use to make it easier to talk about (and yet create a lot of confusion about what is actually happening).

I'm fully aware of this, but thanks for the explanation anyway Wink

Quote
A more complex requirement could say:
"To spend this output you must supply a valid ECDSA signature from any one of the private keys that are associated with either address A or address B"

This is commonly called an M of N transaction where M is 1 and N is 2.  In other words, If the person that controls the private key to address A is not the same person as the one that controls address B, then either one of them can spend the output (whoever spends it first wins).

That's exact what I'm talking about: customizing the transaction so that it appears that a sum was sent to address B, while instead the sum can be claimed by fulfilling a different condition than "having address B's private key".

Quote
Such a requirement would be obvious though.

For someone analyzing the raw transaction, maybe. But would a wallet software be able to recognize it? Could a transaction be crafted to fool a wallet into telling the user "I received this sum" while instead there is a way for someone else to spend it?
legendary
Activity: 3472
Merit: 4801
There is no sum deposited into an address.

There is only an output encumbered with a requirement that must be met to spend that output.

If the requirement says:
"To spend this output you must supply a valid ECDSA signature from the private key that is associated with address A"

Then as a short hand way of talking about the transfer of control of value, we humans say:
"The bitcoins were sent to address A"

Notice, there are no bitcoins, there is no actual sending, and there is no deposit.  There is only an output and a requirement.  Everything else is an abstraction that we humans use to make it easier to talk about (and yet create a lot of confusion about what is actually happening).

A more complex requirement could say:
"To spend this output you must supply a valid ECDSA signature from any one of the private keys that are associated with either address A or address B"

This is commonly called an M of N transaction where M is 1 and N is 2.  In other words, If the person that controls the private key to address A is not the same person as the one that controls address B, then either one of them can spend the output (whoever spends it first wins).

Such a requirement would be obvious though.  If the owner of the private key to address A supplies address A as a receiving address, it would not be possible for the payer to create such an M of N transaction without the receiver's knowledge.
full member
Activity: 168
Merit: 100
A standard Bitcoin transaction deposits coins into an address and then, using Bitcoin's scripting language, states that whoever wants to spend this output must be in possess of the private key corresponding to that address.

However, it's possible to deviate from this base template to create more complex transactions, where other conditions must be met in order to spend the transaction output.

Is it possible to create a transaction where a sum is deposited into an address, but only the owner of another private key is allowed to spend it? I'm not a Bitcoin scripting expert, but this looks at least possible.

In this case, can such a crafted transaction be used to mount a double-spending attack, where address A sends sum X to address B, but after the transaction is completed address A retains ownership of the sum and can send it elsewhere, while address B can actually do nothing about it even if the sum is credited to its balance?

How would a standard wallet treat such a transaction? Would it even recognize there's something strange going on, or would it blindly display that X BTC entered address B, regardless of the transaction script?
Jump to: