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,
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
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
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: <...>
... 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
when trying to access that server. It is very important to allow Android to
check the hostname for you, which is the default behavior.
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.