Author

Topic: Best way to handle user withdrawals of bitcoin? (Read 1212 times)

jlp
sr. member
Activity: 266
Merit: 264
February 09, 2014, 10:25:28 PM
#1
I need to enable my users to send and withdraw bitcoin to and from my web app.  Ideally, this is done immediately or in near real-time.

Using a third-party payment processor, such as BitPay or Coinbase, is not an option for my service.

I've narrowed it down to two options, with only the first one that is able to automate withdrawals.  (Blockchain.info was ruled out due to complaints about unreliability.)

1)  USE BITCOIN'S API VIA JSON-RPC

In this option, I will run my web app, Bitcoin software (Bitcoin-QT/bitcoind) and wallet on the same server.  When the user wants to send bitcoin, I will use JSON-RPC to call getnewaddress() via Bitcoin's API and then show address to users.  I will use Bitcoin options such as walletnotify to notify me when a user has sent bitcoin to my wallet.  I will use blocknotify to prompt me to call gettransaction(), to get the number of confirmations on these transactions.  If the number of confirmations is > X, then my web app will tell the user that his bitcoins are now available in his account.  This can take up to an hour to wait for X confirmations.

When the user wants to withdraw, my web app will get the user's address and then use sendtoaddress() to send bitcoin to the user.

How do I secure Bitcoin and the wallet?  If an attacker hacks into my server, he can change my programs that call JSON-RPC or read the rpcuser and rpcpassword settings in bitcoin.conf and simply call sendtoaddress .  Someone suggested that web apps run Bitcoin and the app on different servers.  However, I don't see how this will increase security.  If an attacker hacks into the Bitcoin server, I would think that he can easily empty the wallet by running curl commands to http://127.0.0.1:8332 or JSON-RPC commands.

Then I read on posts that people should keep a minimal amount of bitcoin on the server's wallet, such as keeping a maximum of BTC0.001 on the server.  I assume that the way to do this, is to send any balance in excess of BTC 0.001 to my offline wallet.

However, aren't there still security holes in this?  If an attacker hacks the server, he can change my code so that my code sends the excess BTC to his address instead of mine.  Or, he can change my code to call getnewaddress() from his wallet instead and show his address to my users. This way, my users will be sending bitcoin to the attacker instead of me.  Or, he can hack into my server repeatedly to steal BTC 0.001 each time.

How do we solve these security problems with Bitcoin?

2)  ADDRESSES ONLY (NO PRIVATE KEYS) ON SERVER

I understand that I can use Armory's watch-only online wallet on my server and Armory's offline wallet on my home computer to maximize security.  (I must be able to test with testnet coins.  Apparently, Armory supports testnet but Electrum does not, hence my choice with Armory.)  However, this means that anytime one of my users wants to withdraw, I would have to manually send the bitcoin to the user, which will make the user wait.  Has anyone had experience with this method?  Was this acceptable to your users and how many users requested withdrawals every day?  Can I use JSON-RPC to call Bitcoin's API to get addresses, balances, etc., from Armory's watch-only wallet?

With this method, it still doesn't seem very secure because an attacker can hack my web app to bypass my wallet.  As an example, can't an attacker (such as the datacenter's employee or an attacker putting in an order to have a Virtual Keyboard and Mouse installed so that the attacker can get console access) hack my web app program so that it calls getnewaddress() from his wallet instead of my Armory watch-only wallet?  Again, this will make my web app show the attacker's address instead of mine and hence, the user will be sending bitcoin to the attacker instead of me.  Has any web app been hacked this way?

Another method is described at http://bitcoin.stackexchange.com/questions/10470/how-to-run-a-bitcoind-on-a-hosting-securely.  With this method, can't an attacker hack my server's database and replace my addresses with his?

Is there a way to automate user withdrawals without compromising security?  Or, must I send bitcoin to users from an offline wallet, which doesn't seem 100% secure and which will make users wait?  What is the best architecture for this?  Is there a solution?

I would think that if there weren't so many security issues, complexities and attackers/hackers associated with Bitcoin, Bitcoin adoption would be much more widespread as many more services, including mine, will be available to bitcoin users.
Jump to: