Author

Topic: MtGox: Easy fix #2. Unique change addresses. (Read 974 times)

donator
Activity: 1218
Merit: 1079
Gerald Davis
February 10, 2014, 01:32:38 PM
#7
I think the larger issue is that building a "wallet" isn't that hard, but building a "node" actually is.  The problem is that the existing reference client combines these distinct entities into a single unified codebase.   bitcoind is a node, wallet server, and RPC client all combined into a single unified codebase.   

This makes extending the reference client in any sustainable way nearly impossible.  For example an enterprise solution might want to use a true relational database to store, query, and update payment statuses.  There is no good way to extend the current reference client to do that.  So you have two "choices", you can use bitcoind and RPC calls but throughput is very low, or you can build a new custom node implementation with all the risks that entails.  Neither is a particularly good solution.

What would be better (I have said this before but I don't think it got any traction) would be to refactor the existing client into separate projects.

Instead of a single project it would consist of multiple projects:
Bitcoin Core - A library which handle the low level functionality of a node.
Bitcoin Node - A reference implementation of the core library which only implements the functionality of a node (think bitcoind minus the rpc client & no wallet)
Bitcoin Wallet - An implementation of a wallet which communicates via a fast, low latency protocol with bitcoin node.

This would give developers options to extend "bitcoind" to custom applications. 

The safest and easiest option would be to design a custom wallet which meets the needs of an enterprise that communicates with the reference bitcoin Node.

More ambitious projects could push lower in the project stack.  Take Bitcoin Armory for example.  Currently it requires an install of "Bitcoin QT" which it then doesn't use for anything but a node implementation.  Initially that could be replaced with Bitcoin Node and likely over time Armory could just make calls directly to bitcoin core.

When developers ask questions about extending Bitcoin they could be steared away from making changes to bitcoin core library directly.

In case this isn't clear let me give you an example.  Take OpenSSL.  It is a library.  People import that library into a variety of projects.  Consumers of that library don't modify the library directly, they extend it.  Now imagine instead if OpenSSL wasn't a library but instead an entire webserver implementing openssl.  So the only option for bitcoin to use it would be either building an installing the entire uneeded server and then passing requests between bitcoin client and the openssl webserver or hacking around in the open ssl source code hoping you don't make an implementation bug.  Both "solutions" would suck.   That is kinda where bitcoin is right now. 
legendary
Activity: 1792
Merit: 1111
February 10, 2014, 01:31:03 PM
#6
Second fix I've come up with for you in the past hour of being awake (spent the first 30 mins of it freaking out after seeing btc-e price too). Use a unique change address for each withdrawal. Makes it easy for you to know if a withdrawal went though

if (deposit to change address)
{
withdraw succeeded
}
else
{
reissue transaction
}

I think they always use unique change address.

However, it seems to me that this is not the problem they are facing. The real problem is that they failed to check whether an input is unspent
donator
Activity: 1218
Merit: 1079
Gerald Davis
February 10, 2014, 01:22:18 PM
#5
But if the attacker makes a payment to his own change address, he just confirmed his own withdrawal. Unless you're saying a 3rd party attacker would be doing it to screw with other's transactions with no personal gain.

Ah yeah your right. Not sure what I was thinking.  Still I think any custom implementation is best served by emulating the bitcoind behavior as closely as possible.  I would recommend checking inputs and output but your solution is far better than what MtGox did.




legendary
Activity: 1260
Merit: 1000
Drunk Posts
February 10, 2014, 01:13:02 PM
#4
But if the attacker makes a payment to his own change address, he just confirmed his own withdrawal. Unless you're saying a 3rd party attacker would be doing it to screw with other's transactions with no personal gain.
donator
Activity: 1218
Merit: 1079
Gerald Davis
February 10, 2014, 01:07:49 PM
#3
Second fix I've come up with for you in the past hour of being awake (spent the first 30 mins of it freaking out after seeing btc-e price too). Use a unique change address for each withdrawal. Makes it easy for you to know if a withdrawal went though

if (deposit to change address)
{
withdraw succeeded
}
else
{
reissue transaction
}

That could be tricked by the attacker making a payment to the change address if the amount of the change is small relative to the amount of the payment.  There is nothing wrong with using tx id for record keeping just understand tx id can be changed.  It is very rare and it requires a deliberate act (tx hashes aren't just being randomly changed by the thousands as the propagate the network).

When a new block is received:

For all unconfirmed transactions:
If the block contains a tx with a matching hash, the tx is now confirmed. 
      Update internal records and set number of confirmations to one.

If the block contains a tx with the same inputs & outputs but has a different tx hash.
      Update internal records and set the tx hash to the new hash value and set number of confirmations to one.

For all confirmed transactions: 
If the number of recorded confirmations in internal records is less than the # your business requires (i.e. <6) check that the new block extends the chain containing the block containing the tx
     Update number of confirmations to be the difference in block height.

legendary
Activity: 1428
Merit: 1000
February 10, 2014, 01:07:20 PM
#2
Second fix I've come up with for you in the past hour of being awake (spent the first 30 mins of it freaking out after seeing btc-e price too). Use a unique change address for each withdrawal. Makes it easy for you to know if a withdrawal went though

if (deposit to change address)
{
withdraw succeeded
}
else
{
reissue transaction
}

this could make problems if you are using multiple wallets which needs to keep in sync (i dont know if mtgox uses that though).
the easiest solution is still: do what the reference client does!

instead of txid just use in/ouputs as a comparison. problem solved.
legendary
Activity: 1260
Merit: 1000
Drunk Posts
February 10, 2014, 12:51:34 PM
#1
Second fix I've come up with for you in the past hour of being awake (spent the first 30 mins of it freaking out after seeing btc-e price too). Use a unique change address for each withdrawal. Makes it easy for you to know if a withdrawal went though

if (deposit to change address)
{
withdraw succeeded
}
else
{
reissue transaction
}
Jump to: