SSL on Android: About That Man in the Middle

(In thanks to The Guardian Project for some assistance in assembling this material, I am blogging a portion of The Busy Coder’s Guide to Android Development Version 4.6 that covers SSL on Android. This is the second part of a four-part series. The other parts include:

Note that if you are reading this in late 2013 or beyond, the material in the book may be newer than these blog posts.)


Man-in-the-middle attacks are a common way of trying to intercept SSL encrypted communications. The “man” in the “middle” might be a proxy server, a different Web site you wind up communicating with via DNS poisoning, etc. The objective of the “man” is to pretend to be the actual Web site or Web service you are trying to communicate with. If your app “falls for it”, your app will open an encrypted channel to the attacker, not your site, and the attacker will have access to the unencrypted data you send over that channel.

Unfortunately, Android apps have a long history of being victims of man-in-the-middle attacks.

Fahl, Harbach, Muders, and Smith of the Leibniz University of Hannover, and Baumgärtner and Freisleben of the Philipps University of Marburg, conducted research on this problem. Their results, as reported in their paper, “Why Eve and Mallory Love Android: An Analysis of Android SSL (In)Security”, is depressing. One in six surveyed apps explicitly ignored SSL certificate validation issues, mostly by means of do-nothing TrustManager implementations as noted above. Out of a selected 100 apps, 41 could be successfully attacked using man-in-the-middle techniques, yielding a treasure trove of credit card information, account credentials for all the major social networks, and so forth.

Their paper outlines a few ways in which apps can screw up SSL management – the following sections outline some of them.

Disabling SSL Certificate Validation

As mentioned above, if you disable SSL certificate validation, by implementing and using a do-nothing TrustManager, you are wide open for man-in-the-middle attacks. A simple transparent proxy server can pretend to be the real endpoint – apps ignoring SSL validation entirely will trust that the transparent proxy is the real endpoint and, therefore, perform SSL key exchange with the proxy rather than the real site. The proxy, as a result, gets access to everything the app sends.

Ignoring Domain Names

A related flaw is when you disable hostname verification. The “common name” (CN) of the SSL certificate should reflect the domain name being requested. Requesting https://www.foo.com/something and receiving an SSL certificate for xkcdhatguy.com would be indicative of a mis-configured Web server at best and a man-in-the-middle attack at worst.

By default, this is checked, and if there is no match, you will get errors like:

javax.net.ssl.SSLException: hostname in certificate didn't match: <...>

where the ... is replaced by whatever domain name you were requesting.

But some developers disable this check. Perhaps during development they were accessing the server using a private IP address, and they were getting SSLExceptions when trying to access that server. It is very important to allow Android to check the hostname for you, which is the default behavior.

Hacked CAs

The truly scary issue is when the problem stems from the CA itself.

Comodo, TURKTRUST, and other certificate authorities have been hacked, where nefarious parties gained the ability to create arbitrary certificates backed by the CA. For example, in the TURKTRUST case, Google found that somebody had created a *.google.com certificate that had TURKTRUST as the root CA. Any browser – or Android app – that implicitly trusted TURKTRUST-issued certificates would believe that this certificate was genuine. This is the ultimate in man-in-the-middle attacks, as code that is ordinarily fairly well-written will believe the CA and therefore happily communicate with the attacker.

In upcoming posts, we will discuss some things you can do to deal with hacked CAs or other MITM attacks.