Coinbase Android Security Vulnerabilities

I contacted Coinbase about some security vulnerabilities in their Bitcoin Wallet and Coinbase Merchant apps via their white hat program. Sadly, they disagreed with the security issues I brought to their attention. Fortunately, these issues are very easy to resolve and I have strongly urged them to do so. I am disclosing them here to alert the public of these security risks and so their users can take necessary action protect their money.

SSL Certificate Verfication

Coinbase wisely recommends that all clients of their API should validate the SSL certificate presented to prevent MITM attacks. However, they fail to do this in their own Android applications.

This leaves open the opportunity for a MITM to present a spoofed SSL certificate. A spoofed certificate could be a SSL Certificate with a valid signing chain whose root siging certificate authority is already installed on the device. For example, a certificate from Verisign instead of from DigiCert (Coinbase's actual certificate authority). In this case, no additional certificate authority would need to be installed on the victim's device. However, if the attacker has access to the device, it is very easy to install an additional certificate authority which the spoofed SSL certificate would have been signed by.

API Key Security

Coinbase has failed to adequately protect their application's API client_id and client_secret. They are published in the source code on GitHub and visible during the authentication process if a man in the middle attack (MITM) is established, which I've outlined above.

Here is the POST request to during the auth process. The client_id and client_secret are clearly visible.

POST /oauth/token HTTP/1.1
Content-Length: 302
Content-Type: application/x-www-form-urlencoded
Connection: Keep-Alive
User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.4)


... and here is the response. Once the attacker has beaten the SSL connection, they can view the access_token.

HTTP/1.1 200 OK
Server: cloudflare-nginx
Date: Wed, 02 Apr 2014 04:02:42 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: [Redacted]
Cache-Control: no-store
Etag: "eda4841ff7d50a67a6b1facca8018527"
Pragma: no-cache
Status: 200 OK
Strict-Transport-Security: max-age=31536000
Vary: Accept-Encoding
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Rack-Cache: invalidate, pass
X-Request-Id: 63349570-36d9-413a-b9cb-31912f85ca04
X-Runtime: 0.029784
X-Ua-Compatible: IE=Edge,chrome=1
CF-RAY: 114a21e0dc560502-SEA


Modifying & Repeating

With a client_secret exposed, requests can be resigned with a valid signature (documentation here) allowing the attacker to repeat or modify requests.

Putting It All Together

Because an attacker has a valid client_id, valid client_secret, and the ability to defeat the application's SSL connection, requests can be viewed, repeated, and modified by an attacker. The attacker can also use these vulnerabilities make API requests at a later time using an access_token stolen during a authentication response.

Potential Harm

With a compromised SSL connection, an attacker could gain full control of a user's account by stealing their access token. An attacker could also intercept a request to send bitcoins and change both the amount and destination address. In short however, they pretty much have full access to the victim's account.

Recommendations to Coinbase Users

Recommendations to Coinbase

Timeline of Disclosure