There’s hardly a mobile app that relies solely on static content. And in order to load content dynamically, http-based protocols are most often used. In this article, I will tell you some things you should be aware of when using an http connection with SSL and how you can avoid man-in-the-middle attacks.
From a security point of view, the client-server connection of your app is highly important, since it often transmits usernames and passwords as well as confidential or legally protected media and information. Let’s assume, for instance, that our app downloads a video from our server in order to play it. The video would be reached via a link such as this one:
Now, it’s very important that the link location does not become publicly known. And it should be impossible to guess as well, since that would obviously undo any security measures taken. Here, this is achieved through a long (128 bit in this case) subfolder, which is a pretty common approach (taken e.g. by Dropbox’ Share Link function).
Some Problems and their Possible Solutions
An attacker will not only try to guess your URL, but also to use it to transfer data. Without any encryption, the URL can be sniffed pretty easily. On the user side, this can for example be done at the WIFI router to which the smartphone running the app is connected. To do this successfully, an attacker would need some network skills, but they would by no means have to be a network administration expert. Additionally, everyone who has access to the network nodes between the device and the server can also gain access to the URL.
The first obvious and definitely very necessary step is securing the connection via SSL. Our link would then look like this:
Now, the attack method described above would only yield the server IP and (usually) also the hostname (my-app.codefluegel.com). That’s already a vast improvement towards a secure connection, but with a little expert knowledge an attacker could still get the link without too much trouble. To do that, they would probably use a so-called man-in-the-middle attack.
Man-in-the-middle (MITM) Attacks
Https connections guarantee end-to-end encryption. All that means is that only the two endpoints (client and server) can see the communication data as plain text. This connection is marked with a green dotted line in the following diagram.
A MITM attack can sidestep this secure communication by establishing two different connections, unbeknownst to the server and the client. The first connection is established between the client and a third party in the local network (we’ll just call this one the ‘attacker’) and another one from the attacker to the server. A fake SSL certificate and a DNS entry in the local network which connects the hostname my-app.codefluegel.com with the local IP of the attacker is enough to make the client think that the attacker is actually the server. Additionally, the attacker also establishes a connection to the real server pretending to be the client. Thus, the attacker can decrypt the communication data from the client and re-encrypts them in order to send them to the server. This way, the attacker can access the entire communication and even send false data.
An attack like that can be implemented relatively easily, and once you’ve done one, you can easily reuse it for any app or website.
Preventing MITM Attacks
In order to be able to handle this kind of security problem, the app must contain a client-certificate. When establishing a connection, the server can then check whether the client uses the provided certificate. Such checks can be performed by most standard webservers – you can find an exemplary configuration for nginx here.
Now, the server will not accept the attacker’s fake SSL certificate and the attack described above can no longer be performed. Also the client can double-check the server certificate. In order to make sure that the download will always work, the expiration date of the client certificate should be well in the future.
The method described above will protect you from MITM attacks for the most part, but perfect security can really never be guaranteed. Some possible security risks are:
– Wrong implementations in your code or in the SSL library (see Heartbleed bug)
– Sniffing the client certificate and the certificate key from the app package (.ipa or .apk)
– Disclosure of the server SSL key (usually due to careless handling)
– Critical security bugs in the used algorithms or in the SSL protocol
Some of these risks can be minimized with a little effort, but they can never be completely eliminated.
There is no perfect security in data transmission. But the risk of interceptions can be drastically reduced by using SSL and certificate checks. If you’d like to know more, just drop us an email.