Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Clone this wiki locally
To a large extent, the security of the whole system will depend on how it's deployed, how it's integrated with other systems and how well it's monitored and maintained. That's why every deployment of txbits will have different levels of security. Later on we are going to publish some information that is designed to help set up the exchange securely. For now, this document is a good overview of what needs to be considered when thinking about the security of the exchange.
Before we talk about how we are securing our data, we need to mention what we are securing. There are a few major assets we need to protect:
- User database including passwords
- Transaction history
There are a few main categories of attack vectors:
- Attack on the users (malware, phishing, MITM attacks)
- Attack through the web application (SQLi, RCE, XSS)
- Attack through the admin interface (openssh vulnerabilities, default passwords, etc.)
- Attack through the hosting provider (if on a VPS)
- Physical attack (if on a dedicated server in a colo)
- Attack through an administrator's work machine (malware, etc.)
In this document we are concerned with number 1 and 2 only. The rest is up to whoever is deploying the application and defenses will vary depending on specific circumstances.
Defending the user (attack vector 1)
We have a strong password policy and we encourage users to use a password manager to store their password instead of using an easy to remember password. We have no limit to the length or complexity of passwords.
Two factor auth
Two factor auth is done using Goole authenticator (TOTP) for now. Later we might add SMS, email and other options. There is no mechanism for recovering a forgotten two factor auth code, but we will do something similar to gmail and wordperss where the user has to store a list of backup one time use codes.
Secure password reset
Password reset does not circumvent two factor auth. We don't use "security questions" that other people can guess. We offer the option to encrypt all emails to you using PGP so even password reset emails are secured with that.
Authentication security finite state machine
The following finite state machine describes the different levels of security that the user can have depending on whether they use two factor auth and/or PGP.
When a user resets their password, all of their sessions are logged out automatically. When a user is inactive for some amount of time, their session is destroyed. There are several edge cases in these sorts of systems and we hope to have covered all of them. Let us know if we are handling any of them wrong.
We support TLS 1.0, 1.1, 1.2. We don't support SSLv3 or lower. We encourage everyone who runs a copy of txbits to also do that. This means that IE6 on Windows XP will not have any way to connect, but that's okay. If someone is using Windows XP to trade cryptocurrencies, we are doing them a favour by not allowing them to connect.
We support and encourage perfect forward secrecy and elliptic curve based cipher-suites.
Defending the servers (attack vector 2)
The security of the exchange consists of several layers.
Let me draw you a picture of how the three main parts connect:
|h4x0r/user| -> |frontend| -> |database| <- |wallet| -> |bitcoind| -> *the clooouuud* | ^ \----> |litecoind| -> *the clooouuud* | | | |user trust service| | | \---------------\-------> |mail server| <-> *the clooouuud*
The arrows show the direction of network connections.
As you can see, the actual crypto coins are stored far away from the frontend so that an attacker would have to penetrate multiple levels of defense before they can reach the wallet.
The user trust service is what sends emails that contain secrets that users have to provide to the frontend to authorize actions. For example, when a user requests to reset their password, the frontend doesn't see the password reset token. The user trust service generates and send it to the user. The frontend receives the token only when the user clicks on the link in the email. The same mechanism is used to secure withdrawals.
We will look at how our defense works in terms of what it would take to get to our main assets.
Attacking the user database (assets 2 and 3)
Layer 1 - remote code execution / SQL injection
We have no way to prevent developers from concatenating unsafe strings into SQL statements, but our standard way of constructing SQL queries makes that very difficult. The probability of having a SQL injection vulnerability is negligible.
We use Play, which has not been battle tested as extensively as some other web frameworks, so it's entirely possible that someone finds a remote code execution vulnerability in it, but I would still say the chances are low.
Layer 2 (optional) - root on the frontend server
Some attacks on postgres may require root privileges on the frontend machine in order to craft raw packets. This is why this layer may or may not be required.
Regular linux system permissions should prevent an attacker from gaining root after they've exploited the frontend. It's up to the system administrator to make sure this is hard.
Layer 3 - database admin
The attacker may not need to go through layer 2 to get here, but they need to get here before they can get to the user data.
The database user used to talk from the frontend to the database does not have permissions to access user passwords or account history directly. This requires database admin privileges. To get said privileges, an attacker must rely on a misconfiguration in postgres or an unpatched vulnerability.
Layer 4 - offline attacks on the leaked database
Passwords are hashed and salted with a slow hashing function. In the event of a database leak, it would take attacker too long to guess many passwords. This gives the administrator time to react and make everyone reset their password.
The email list can be abused by the attackers to send phishing attacks. This is up to the administrator to protect against. DKIM, SPF, PGP and pain-text-only emails can help with this.
At this point all transaction history will be public, and there's nothing that can be done to prevent this other than archiving older history and removing it from the server. We don't currently have an easy way to do this, but it can be implemented.
Attacking the private keys (asset 1)
The same layers as before apply (except layer 4 maybe), plus one extra layer:
Layer 5 - database to wallet server
The database should not be allowed to connect to the wallet directly. This means that in order to attack the wallet from the database, you have to wait for the wallet to connect to you. This kind of attack might lead to taking the website offline if it's not done carefully. It would have to exploit some flaw in the postgres JDBC driver that leads to remote code execution on the client side.
We expect this to be hard to do, but you never know... That's why we have layers.
Online attacks from the frontend (assets 1, 2 and 3)
The most effective attack that can be done is for the attacker to get unprivileged access to a frontend server and replace the frontend with their own modified version. This reqiures only penetrating layer 1 and maybe 2. It gives them temporary access and we hope that they will be discovered within a reasonable amount of time. This kind of access gives them the ability to do the following only to currently logged in users:
- Steal passwords
- Request withdrawals on behalf of users (that the users will receive an email to approve)
- Change the destination addresses for withdrawals (which can be detected by users!)
- Make trades on behalf of users
- Read user account history
We are in a very good position to defend such attacks because of our architecture. These attacks are applicable only for users who have logged in during the period of time when the frontend was compromised. We make it very difficult for an attacker to make a fake withdrawal. We have an out-of-band email based verification initiated by the wallet. An attacker is not be able to make a withdrawal if they control only the frontend server. They need to control the front end as well as the email, database or wallet server.
Attacks on *coind (asset 1)
Cryptocoin wallets only ever connect out to the Internet and should be firewalled off from receiving any incoming connections. As an extra layer of precaution, the administrator could specify a small list of nodes that their wallets are allowed to connect out to. This minimizes the exposure in case of a catastrophic bug being found in a coin's software.