Author

Topic: bitcoind security (Read 1597 times)

hero member
Activity: 756
Merit: 522
May 02, 2013, 02:29:06 PM
#10
I'm in the process of creating a web application that will create and process transactions using bitcoind.

I'm trying to design the solution in such a way that if the web server machine were compromised it would be more difficult to access the hot wallet.

The concept is to utilize message queues (for example, amazon's SQS)

When a transaction was needed the web server would create a message and send it to the message queue.

Disconnected and unknown to the web server another server (let's call it bitcoind server) is checking for messages on the message queue. When a message is received the bitcoind server processes the message, and it could optionally return a message via a message queue that the web server could pick up.

The bitcoind server would in no way be connected or associated with the web server or the database used by the web server.

Here's a simple example:



Therefore, if the web server were to be compromised you would need to a) figure out the key to encrypt the message; b) figure out the authentication mechanism for the message queue; and c) defeat any transaction limit / validation checking.

I realize it does not completely eliminate a threat, but it does reduce it substantially.

Does this approach seem valid? Is the increased security worth the effort / complexity increase? How should this approach be improved?

The MPEx model, practically speaking. Read up.
hero member
Activity: 616
Merit: 522
May 02, 2013, 05:36:47 AM
#9
Oh wait, I like the way you write, let me try.

Thank you sir for your insightful post. Your comprehension and implementation of security protocols it beyond mesure. It is a pity this forum lacks a tip bot, but I can assure you there will be incoming btc to the address you provided.

lol, thanks.

I would assume that you have a database with the user balances on your web server, otherwise how can the server be displaying account balances, etc.

Therefore if the hacker gets into your web server, logs on to the database, increases his own user balance and then withdraws via the standard appliction interface?   To be on the safe side he probably deducts the amount he added to his account from another account just incase you match total wallet balance with total account balance.

This is another issue which the verification server could verify independently. Maintain independent copy od user balances along with all previous transactions that summed up should give equal balance that the stored balance. Confirm all new transactions that were found in the database with blockchain / some other ledger to make sure that they actually took place. Alert when anything has changed in previously stored transactions (so that would detect if hacker switched some other user past transactions/deposits to his account to increase his balance).

You just think about the verification server as the cop who never trusts the web server and always needs to get additional verification from independent source to confirm anything what web server or main database claim (“So you said that user balance changed from 1 BTC to 1000 BTC, okay, show me what deposit was that... oh wait, there's no such transaction in blockchain / oh wait, I heard about that transaction before and it was made by another user”, etc). Then think of anything that hacker might forge on your web server and think about how your cop could verify that in an independent source. This is the way to go.

This still has one flaw. If hacker changes your web app to alter deposits made by other users to be associated with his user id (since after the hack). As the verification server can only confirm in the blockchain if the transaction is actually there and confirm in its database if the transaction wasn't already processed, this would look innocent and could be scored into hacker's account. But the legit user making a deposit wouldn't see that deposit nor the increased balance and would contact support (and there would be many such users). The hacker couldn't increase both user balances as it would not match with transaction log on the verification server (and that should alert you and/or stop temporarily some features as there's only two cases when something won't match here - server hack or some major bug).

So this would be a possible attack vector - to alter in realtime only transactions that are happening from after the hack - but it could affect only deposits made after the attack and would be detected quickly. And... there is another double checking procedure that we might think on to prevent that from happening. E.g. create 100 one-time deposit addresses for each user on his signup. Now the hacked web server can't claim that some deposit should go into hacker's account balance, as the verification server knows that the address is associated with another user. So we just killed another attack vector possibility in that simple way.

There could be 100-pages specification written about this if we wanted to include all use cases and scenarios. So I am only showing the way to think and the pattern to use two independent sources to confirm every sensitive action. For every sensitive action you can think of, think on how it might be compromised and then think on how to confirm it using another source, independent of your web sever and your production database.
hero member
Activity: 525
Merit: 500
May 02, 2013, 04:20:15 AM
#8
I would assume that you have a database with the user balances on your web server, otherwise how can the server be displaying account balances, etc.

Therefore if the hacker gets into your web server, logs on to the database, increases his own user balance and then withdraws via the standard appliction interface?   To be on the safe side he probably deducts the amount he added to his account from another account just incase you match total wallet balance with total account balance.
sr. member
Activity: 351
Merit: 250
May 01, 2013, 04:59:37 PM
#7

a. user uses application on the web server and requests a withdrawal.
b. web server sends sqs message “hey, user A just requested to withdraw X BTC, let's call it transaction id-123, can we do that?”.
c. verification server gets that and thinks “alright, let's just make sure that web server isn't lying”. It sends an email message to the user to get second confirmation: “hey, just to make sure that it's you who wanted to withdraw, please confirm by clicking on this link”. So it's the verification server that sends the message. Hacker who compromised the web server has no way of intercepting that message.
d. user gets an email and clicks on the link. The link leads to the web server again (we don't want anyone to know our verification server address). The web server now gets that secret token generated by verification server and sends another message to the verification server: “alright, I'm a bit affronted that you asked the user to confirm my message, but here we go; the user confirms the withdrawal and he passed this token as confirmation: xxxxxxxxx”.
e. the verification server now can be sure that since web server knows the token, which was sent directly to the user, that the web server is acting in the name of the user. the verification server now sends the message to the bitcoind server “I hereby testify that the transaction id-123 to withdraw X BTC for user A is legit”.
d. the bitcoind server gets two messages: from web server to process transaction id-123 to withdraw X BTC for user A; and the confirmation from the verification server that transaction id-123 to withdraw X BTC for user A is legit.


That's bitchin' cool! I get it now. That seems rock solid!

Oh wait, I like the way you write, let me try.

Thank you sir for your insightful post. Your comprehension and implementation of security protocols it beyond mesure. It is a pity this forum lacks a tip bot, but I can assure you there will be incoming btc to the address you provided.

Cheers!
hero member
Activity: 616
Merit: 522
May 01, 2013, 04:41:05 PM
#6
b. web server sends decode key in a link via email to user

You have it wrong here. The whole point of such design is to create a system where particular servers don't trust each other and require additional confirmation from independent source.

What you wrote here is like verification server sends back to web server a message: “thanks for the withdrawal request, but could you make sure that it's actually user who requested it”? That would need to rely on belief that web server won't lie.

I'll write it again in other words:

a. user uses application on the web server and requests a withdrawal.
b. web server sends sqs message “hey, user A just requested to withdraw X BTC, let's call it transaction id-123, can we do that?”.
c. verification server gets that and thinks “alright, let's just make sure that web server isn't lying”. It sends an email message to the user to get second confirmation: “hey, just to make sure that it's you who wanted to withdraw, please confirm by clicking on this link”. So it's the verification server that sends the message. Hacker who compromised the web server has no way of intercepting that message.
d. user gets an email and clicks on the link. The link leads to the web server again (we don't want anyone to know our verification server address). The web server now gets that secret token generated by verification server and sends another message to the verification server: “alright, I'm a bit affronted that you asked the user to confirm my message, but here we go; the user confirms the withdrawal and he passed this token as confirmation: xxxxxxxxx”.
e. the verification server now can be sure that since web server knows the token, which was sent directly to the user, that the web server is acting in the name of the user. the verification server now sends the message to the bitcoind server “I hereby testify that the transaction id-123 to withdraw X BTC for user A is legit”.
d. the bitcoind server gets two messages: from web server to process transaction id-123 to withdraw X BTC for user A; and the confirmation from the verification server that transaction id-123 to withdraw X BTC for user A is legit.

This way, you always require two separate sources that tell the transaction is legit. bitcoind requires a message from web server that is confirmed with another message by the verification server. The verification server requires user confirmation of the message sent from the web server.

This is also the reason to separate the verification and bitcoind servers. If someone, shomehow hacked your verification server, it won't be enough - he would need to hack both web and verification servers. Your verification server will connect to the same database that your web server and this is the way someone could find the verification server IPs (I admit it's a bit paranoid, but there's no such thing as too paranoid when it comes to security).

Also, remember that it's important for the verification server to independently track user email changes and don't trust web server in that case too. It should sync user email database with its separate verification database and each time user email change is detected, it should send the user notification emails and stop withdrawals for that user for 24 hours. This should also work on the “don't trust the web server” principle (what is equal to “don't trust data in the production database as it's wirteable by web server”).

As for the email sent to the user to verify withdrawal request. This should be a random one-time-use token. If web server sends another message containing that token, it means that the user clicked on the link. No private keys or stuff like that. This should be a one-time token which won't ever be valid for any later transaction.
sr. member
Activity: 351
Merit: 250
May 01, 2013, 08:57:45 AM
#5
Wow! Thanks for that reply. Well thought out. I have a couple of questions.

1. Do you think it makes a difference from a security standpoint if the verification server and the bitcoind server are on the same machine?

2. Attack vectors for the email generation. If I follow correctly, the implementation would be similar to this:

a. web server encodes transaction message and sends to sqs;
b. web server sends decode key in a link via email to user (or maybe the private key is contained on the verification server and this is the random salt used to encode... not quite sure);
c. web server receives url contained in email, grabs the key, and sends it to sqs.
d. verification server uses the message with the key to decode the transaction and pass it to the bitcoind server.

The attack vector would be if an attacker gained access of the web server, sent the tx message, intercepted the email link and manually sent the information in the email link to sqs. I realize in your model the transaction would not be processed within 24 hours of an email change, but this is just an academic exploration of how the compromise of the sqs verification server would occur. Are there any options to reduce this attack vector?

Cheers!

 
hero member
Activity: 616
Merit: 522
April 30, 2013, 09:47:52 PM
#4
Therefore, if the web server were to be compromised you would need to a) figure out the key to encrypt the message; b) figure out the authentication mechanism for the message queue; and c) defeat any transaction limit / validation checking.

Well, if your web server is compromised then all this logic will be available in plain text in your PHP files, so that SQS design doesn't really change much. They probably wouldn't even need to figure all that stuff but simply to execute some of your code.

You might want an independent third party that verifies messages to increase security. That third party should have some information that is required to proceed with transaction but is unavailable to your web server, so that the web server alone couldn't prepare a valid message.

Now what that might be - it totally depends on your application. Let me give you an example assuming that you run an exchange - or any other website keeping people's deposits - and these transactions we discuss are withdrawals requested by users. This would allow for two design choices that might not be possible in a different kind of website, but are perfectly fine in an exchange: 1) each withdrawal needs to be confirmed by clicking a link sent to an user email; 2) no withdrawal is possible in 24 hours after email change.

You have these three servers: web server, verification server, bitcoind server, which are talking to each other using SQS, not knowing each another IP addresses, etc.

So user comes to your website and requests withdrawal. Your web server creates SQS message addressed to your verification server. The verification server creates a confirmation token and prepares a link to send to user email. When user receives the email, he clicks on the link and it's processed again by your web server which sends another SQS message to the verification server. The verification server confirms that the token is valid and creates SQS message for the bitcoind server to schedule the transaction.

Hacking your web server alone allows do nothing, as the verification server needs to generate a token and the token needs to be confirmed by the user. Token travels from verification server -> to the user email -> to the web server after user clicked the link -> back to verification server. And only after that round-trip, the verification server (not the web server) creates SQS message to bitcoind server. They would need to hack both web server + user email or web server + verification server  to do anything. But nobody knows where your verification server is located - they don't know its IP, even your web server doesn't know the verification server IP.

Now there's one more thing to take care of to be really secure. As both web server and verification server would need access to database with user accounts, we need to make sure that hacker didn't change user email address in the users database (he will have write access to it after compromising the web server) just before sending SQS message to verify withdrawal.

So the verification server should have another database (not accessible by web server) with copy of user email addresses and it should keep track of changes in user addresses. It should sync all user addresses from the main database into its own database every hour (or more often) and detect changed addresses. Mark these changed addresses with timestamp on its own (i.e. not depending on any modified_at field in the main database as it might be faked as well). It should not allow any withdrawal for user who changed his address in the last 24 hours. Moreover, on each email change detected, it should send an email to both old and new user addresses notifying him of that change. This is a good practice anyway and by doing that from the verification server you'll make sure that user will always be notified on his email change - even if your web server was compromised and hacker changed the email manually in database (thus not triggering any email change action in your web application), the described process would trigger email notification anyway, because the verification server would detect email change and send the notification.

So now for the hacker to make unauthorized withdrawal would need: 1) hack into your web server; 2) change user email addresses in database; 3) wait for more than 24 hours; 4) in the meantime user(s) would need to ignore changed email notification message which you sent to them from your verification server; 5) only after these 24 hours after changing user emails and users not alerting you of unauthorized email change, the hacker could request a withdrawal; now verification sever sends withdrawal confirmation email to hacker-modified email address so that he can receive the email, confirm the token and the transaction would actually be scheduled. This is highly unlikely, especially when user is notified about email change (and it's done from independent, verification server, so the hacker cannot stop that).

Bonus point: in addition to the user not reacting for email change, the hacker would really need to know how this whole system works, so that he actually needs to make the email change and wait 24 hours. As the code responsible for verification will be on another server, the hacker couldn't read the code and get to know about your internal verification rules, so there's not really any way for them to know about it. Even if they know that no withdrawal are possible within 24 hours of email change, they will probably think that changing modified_at field will do the trick, not knowing that you actually track modification timestamps on a separate server and in a separate database.

Hah, that was long. Sorry I didn't draw any diagrams. I hope I's clear and I hope it helps. Of course if you're not taking about user withdrawals then this exact design might not be possible, but it should give you an idea of how that independent verifying third party might work and how to design such process.
legendary
Activity: 1498
Merit: 1000
April 30, 2013, 06:56:17 PM
#3
I do two things, I do a cold storage, which means I create about 10,000 Addresses, load the public address into a mysql table and pull from that. I have a cronjob that tells me when I get to 1,000 Addresses and I fill it up again. I queue withdraws and manually do them.

My second method is I use a proxy java server, that I built that I can just do calls with a key and it keeps my password in memory for my bitcoind. So the key is different then the password. This proxy server does a lot more too but that is more towards other then things then security. This is a really simple explanation but it is very secure.
sr. member
Activity: 351
Merit: 250
April 30, 2013, 06:48:49 PM
#2
I'm going to bump this up, because I would love to hear some feedback on the model.

If there is agreement that the approach is solid I'd like to create a github PHP implementation of the solution.

Thoughts???
sr. member
Activity: 351
Merit: 250
April 29, 2013, 04:56:00 PM
#1
I'm in the process of creating a web application that will create and process transactions using bitcoind.

I'm trying to design the solution in such a way that if the web server machine were compromised it would be more difficult to access the hot wallet.

The concept is to utilize message queues (for example, amazon's SQS)

When a transaction was needed the web server would create a message and send it to the message queue.

Disconnected and unknown to the web server another server (let's call it bitcoind server) is checking for messages on the message queue. When a message is received the bitcoind server processes the message, and it could optionally return a message via a message queue that the web server could pick up.

The bitcoind server would in no way be connected or associated with the web server or the database used by the web server.

Here's a simple example:



Therefore, if the web server were to be compromised you would need to a) figure out the key to encrypt the message; b) figure out the authentication mechanism for the message queue; and c) defeat any transaction limit / validation checking.

I realize it does not completely eliminate a threat, but it does reduce it substantially.

Does this approach seem valid? Is the increased security worth the effort / complexity increase? How should this approach be improved?
Jump to: