No doubt running a cryptocoin exchange is hard work. You’re constantly fighting an uphill battle to stop attackers trying to get in and take your users coins. Understandably, it is in the best interests of the person(s) running the exchange to ensure due-care has been taken as collecting fees from a long-running site opposed to a hit-and-run led website is more profitable.
Recently, Coinex.pw an exchange with considerable volume for not only Bitcoin, but also Dogecoin was majorly hacked for a second time. All coins on the platform were stolen according to the statement made by lead developer Erundook over at Bitcointalk and will be covered at the expense of Erundook.
And herein lies the real issue with cryptocoin exchanges: they’re inherently insecure.
While I am a somewhat experienced developer, I am not a cryptocoin expert. I don’t know everything when it comes to the development of a cryptocurrency nor the ideal way in which one would work.
I do have a moderate understanding of securing a webserver, configuring firewalls and other protection layers, transactional exchange and banking apps are a whole new ballgame.
As such, this article is purely opinion and should be taken with a grain of salt. These are my own ideas and thoughts on the subject. So please pardon my ignorance if I explained something incorrectly, drop me an email or leave a comment and any inaccuracies will be promptly fixed.
How a cryptocurrency exchange works
So, how does a site like Mt Gox, Coinex or Cryptsy work? Essentially, these exchanges are software applications sitting in-front of multiple cryptocoin wallets. In the case of Mt Gox, it was a website developed in PHP which interfaced with the JSON RPC API of the Bitcoin Wallet. Bitcoin to Paypal in the past was a little tricky, but the internet found its way.
After you’ve created an account and you request a deposit address, a call is made to the Linux wallet client which then returns an address. If an account does not exist, an account usually comprised of the users email address is stored in the wallet and used as a unique user ID.
Depending on the level of complexity involved, an exchange can be comprised of just a small handful of wallet clients all the way up to hundreds of them. Think of it the same way as downloading a Windows or Mac desktop walllet client you use for your day-to-day use of the coins, it works the same way on the server side.
The application is the interface and the wallet(s) are the API(s). The application requests a transfer, address generated, transaction confirmation, the moving of funds, You of course would have a database storing all user details including transactions.
The process might look like this for a deposit:
- User logs in
- User goes to deposit
- User selects their coin
- An address tied to that user only is created as a result of an API call to a wallet.
- The generated address is stored in a table somewhere (most likely a separate addresses or transactions table).
- User via their desktop wallet chooses the amount they want to send and inputs the generated wallet address.
- The deposit is added to the blockchain
- After a certain number of confirmations (individual client holders automatically confirming the authenticity) it is usually about 8, the coins are confirmed.
- The exchange has confirmed your deposit and changes a value in the database (a floating value or integer converted to a floating point value when needed)
- The deposited coins are then usually split up and spread throughout the wallet into different deposit accounts (all on the same chosen client). Some might go to a fees account for site fees, another part might be sent to a “Cold storage processing” account and the other added to a “Hot storage” account.
And that’s just the deposit process. You’ve got to consider withdrawals, table/row level-locks when any funds are modified or moved. Allowing users to trade a coin for another coin (in many ways similar to a withdrawal) is also a process in itself. As with any application, as the complexity increases, the chances of something being not as secure as it can be increase.
So, how do these sites keep getting hacked?
In a lot of cases details of attacks on cryptocoin exchanges aren’t publicly revealed in-depth presumably for security reasons. There are many ways to do it, but the most common is gaining access to the server housing one or more unencrypted hot-wallets and copying them, importing them into a desktop client and sending the funds to various accounts.
Attacks come in all shapes and scale. Ranging from internal attacks from a rogue employee, to security holes in the software layer itself (as witnessed in the Mt Gox situation) that are exploited. A lack of understanding of the bigger picture is what gets an exchange hacked.
What is a hot wallet?
A hot-wallet essentially means connected to the Internet, as opposed to a cold wallet which is not accessible by a network and has to be manually processed. All major exchanges use hot-wallets to a degree, some more than others depending on needs and preferences of the site operators.
These big exchanges given the nature of the amount of requests they would be processing per second (scaled up by the number of users they have) all use hot-wallets. When a user wants to deposit coin, a call is made to a hot-wallet via the JSON RPC API and a wallet address is returned. No hot-wallet means the software can’t communicate to generate addresses, confirm deposits, etc.
And because of the very nature of exchanges the wallet files cannot be encrypted like they would be on a users desktop machine. The issue is you would need to constantly encrypt and decrypt the wallet which would take forever and cause a lot of problems (especially when multiple people are requesting transfers and deposit addresses). You have to realise potentially hundreds of users could all be sharing the same wallet with other site users.
What about security?
Cryptocoin exchanges are similar to banks, the only difference being banks are regulated and accountable under certain laws when shit hits the fan. If a bank loses your money, legally they have to return it and within a reasonable amount of time, most likely face fines and prosecution.
When it comes to cryptocurrency, you’re on your own. If an exchange goes down, you have no chance of getting it back if the exchange can’t cover the loss.
I’ve witnessed and heard of varying degrees of security when it comes to a cryptocoin exchange. Software firewalls, hardware firewalls and creating a distributed network of wallets spread out on multiple machines that shuffle the money around like a pack of cards meaning money doesn’t sit in one spot more than X amount of time.
Each level of security has its own perks and caveats. Software firewalls aren’t always effective, hardware firewalls are uncommon and expensive and a distributed network of hot-wallets (especially ones that self-destruct and recreate themselves) is an uncommon approach not many people would have the skillet to implement in a proper manner.
Securing the wallet files is one thing, but also protecting your user data, identification documents and any other piece of information you’ve collected and stored on a user should also be a parallel high priority. If a user has their account hacked, it can be another method hackers can use to steal coins and no firewall or distributed wallet network can stop that.
How can you protect yourself?
It is rather simple to protect your coins from being lost in a rogue cryptocoin exchange attack. Although keep in mind, there are instances where you could lose coins like during a trade.
- DO NOT store all of your coins on an exchange. The old saying, do not put all of your eggs into one basket rings true here. And if you want to transfer all coins for trading, understand the risks involved (some exchanges have a slow withdrawal process).
- ALWAYS encrypt your wallet files with long and complex encryption passwords (never use the same password twice). A minimum of at least 20 unique characters including numeric, uppercase, lowercase and symbols. Use an application like 1Password to generate and store wallet passwords.
- Make sure you regularly backup your wallet(s) on a daily basis and depending on amount of coins you hold, more frequently. If they’re encrypted strongly, storing your wallet files on a service like Copy or Dropbox can be of great help.
This is more directed at the developers and operators of cryptocoin exchanges than it is everyday users, but good for everyone to read in my opinion.
- WRITE UNIT TESTS FOR EVERY PIECE OF CODE. Every line of important code should have a test case. Unit tests allow you to test out a particular line or module of code; expected outcome, what happens if a transaction fails, what happens if a user is logged out during an active trade, what happens when funds are withdrawn and the user doesn’t have enough coins?It’s 2014, and unit testing code has been a thing for as long as I can remember and yet, a lot of developers still do not use unit tests and prefer to just push rogue untested code live and suffer the consequences later on when it is too late.
- Use deployment tools. Alongside your unit tests, using a tool for automatic deployment like Capistrano can also prevent you from sending an app or line of code live if it has failed a unit test. This is where unit tests are invaluable, when you deploy, tests are run and if they pass, the code is pushed into production, if not, details of the error are shown and which particular test case failed.
- NEVER keep your coins in the one wallet for too long. Ensure your exchange has a process in which large amounts of coins are moved offline into cold storage with only a minimal amount of coins in a hot-wallet. This means if coins are lost, they’re easier to recover and you don’t lose everything. Limit withdrawal limits if you have too, some users might not like it, but smaller withdrawal limits versus losing all of your coins in an attack will always be the favourable option.
- Monitor and log everything. Every action a user makes, every transaction, every login attempt, every IP and location should be logged. You should also be ensuring totals of all balances match the balances the actual wallets are saying they hold. This is where Mt Gox went wrong, they didn’t realise the totals of their users didn’t match the totals of their wallet.
- NEVER EVER just rely on skill and capabilities of developers, use some of the fee money that is being collected to regularly pay for a security audit. Hire a decent security expert who is experienced in transactional systems who will be able to find holes in your system before someone else does. Ideally, someone with cryptocurrency experience would be preferred.
- ALWAYS force HTTPS on your exchange and make sure you have purchased a signed SSL certificate from an accredited authority. While most attacks on exchanges you see aren’t a result of SSL being used or not, they can help prevent attacks on user account passwords/usernames and stop details being sniffed.
- Do not use FTP to transfer files to your server. It always amazes me when I see many developers still deploying websites via FTP. At the very least, use something like SFTP (Secure File Transfer Protocol).
- Do not run exchanges on shared hosting or any other insecure environment you do not control. I’ve seen exchanges running on Linode and Digital Ocean before on virtual private servers, if you’re serious, host it on Amazon’s EC2 service or buy some bare metal servers and pay an expert to set them up for you. There was a pretty famous attack on Bitcoin a little while ago via Linode (you might or might not recall).
- Use passwords and public-key encryption. If someone can connect to your server and just type in root for the username and a password, you’re screwed. Securing your server using both a password and a private key will insure someone can’t just gain root access without the key and password.
- Never ever ever allow direct root access to your server. If you’re running in a Linux environment (and shame on you if you’re not). Always only allow sudo access elevation from within other specified accounts, never allow direct root access via just a username or password/key combo. You’d be surprised how many people I’ve seen that login directly using the root username…