-
Notifications
You must be signed in to change notification settings - Fork 38.7k
Relay and accept transactions that personally benefit the user #1648
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
Conversation
|
Accepting non-standard transactions has already been NAK'd. Putting this into a new pull req doesn't change that. |
|
This has not already been NAK'd. Please reopen so I don't need to keep resubmitting, and consider reading the change to review (this doesn't accept any old non-standard transactions, only ones you make yourself). |
|
The following is an automatic comment from the Bitcoin Pull Tester. This pull passed automatic sanity-tests! |
|
This change is partially, if not totally, flawed. Any user can send a peer a transaction that returns IsMine() == true or IsFromMe() == true if he knows who the peer is (the peer's public key). Creating transactions that return IsFromMe()=true the attacker can bypass penny flooding prevention and IsStandard() and go directly to the CPU-expensive ConnectInputs() code. This creates a perfect DoS attack. He can also skip IsStandard() and put non-standard txs into mapOrphanTransactions. Afterwards he can send a single tx that triggers the verification of thousands non-standard transactions at once, and I'm almost sure this can be used to mount a DoS. Creating transactions with IsMine() = true is also dangerous. The attacker can create a non-standard tx and send 0.0000001 to the victim's address and bypass penny flooding prevention and isStandard(). The peer would blindly relay that transactions to remaining peers. This could be used (although I didn't explore how to do it) to force the remaining nodes to block the victim's node. I find this change very disturbing, from the security point of view. |
|
An attacker can't create transactions that return IsFromMe()==true unless they have already compromised your wallet. No anti-DoS rule should ever be made based on relaying valid transactions, though perhaps concern should be given to potentially filling the victim's memory/wallet with spam. |
|
Why the attacker can't create transactions that return IsFromMe()==true ? The code IsFromMe(Tx) calls (GetDebit(tx) > 0) that calls GetDebit() from each txin, that finds the previous transaction and calls IsMine(prevout) which only checks that the recipient address is a specific key (only works for standard transaction templates). It does NOT check the signatures, just the template. |
|
Some time ago there was a discussion on https://bitcointalk.org/index.php?topic=91915.0 about the purpose of IsStandard() check and its benefits |
|
If the signatures don't match, the transaction is invalid and won't even get this far. |
|
TRUE but you can create a VALID tx that sends 0 BTC to the victim and use the REMAINING previns/txouts to do nasty things. |
|
I think @luke-jr is right here, though I haven't looked closely enough to be sure, so thanks for raising the point. Anyway, this does raise another point: maybe IsFromMe() transactions should not be retransmitted unless they are really created by this instance (and not received from the network). |
|
If that really works, it's a bug (in the existing code). |
|
Nevertheless IsFromMe()=true is just enough of a problem. |
|
If you want your client to allow a "fast track" for your transactions, then you can add some hidden message to the script of the transaction. The hidden message must be a MAC (Message Authentication Code) of your transaction using a secret key. Then you can check very fast that you're the sender of a transaction |
|
No need for something that complex. Wallet transactions already have a fFromMe field which can easily be used to track whether it is not only "from me", but also "created by this instance". |
|
@sipa That sounds like a good idea. How does it work with raw transactions (which are likely the common use case for this)? |
|
Great! (but maybe the luke-jr runs multiple instances in different computers, so fFromMe is not available) |
|
If sendrawtransaction can be made to cause fFromMe to be set then it even covers the multiple instance case, so long as you do the work to trigger it from each instance. (Arguably better than the wallet duplication required to make input sniffing work) |
|
I found two new attacks that breaks pseudonimity and allows a node to discover the peer's public address. With this information in hand (IP and Bitcoin pub address), a hacker may get the real identity and track the users payments. a) Wait to see if the peer relays a non-standard transaction, it it does, then the public key must be the one of the txins or txouts. b)
This is a classical side-channel attack. My opinion: Never branch the code checking IsFromMe() / IsMine() in CTxMemPool::accept() Note that the use of fFromMe does not posses any risks . |
|
@SergioDemianLerner "A" is not a real risk, since relaying the non-standard transaction is the only way to actually use it (so the only way to avoid this risk is to not use non-standard transactions at all). "B" seems like it could have some serious privacy implications, though - do you think it would work better if the client secretly held onto the transaction and only relayed it again later? |
|
"A" could be achieved by sending the transaction directly to the miners (I don't know how to achieve that) . Then only the miners will know who send it. Your idea to hide the transaction is interesting...The node should act exactly as if the transaction had been rejected. Also there should be no timing differences between rejecting and hiding. The only problem I see is that if the attacker has two connections to the victim, then he can monitor if the transaction goes out from the other end, so the attack it still possible... Anyway, why do you want to force to relay transactions that go to you? Your decision to relay/not-relay as a single node in the network has very little probability to influence the fact that the transaction will or won't be included in a block by a miner. It is only relevant if you own a high percentage of the nodes of the network, so you can chain transmissions until a miners node. Maybe what you want is to put the transaction into a special pool to monitor for 0-confirmations, but not for re-transmit. |
|
After thinking about it more, this gains from this seem not worth the risks at this time. |
This is a rework of #1128: