Security – Safe iPhone App to Server Communication

iosruby-on-railsSecurityserver

What would be the best approach to achieving private communication between my iOS app and its server component? Is having a single unchanging “secret key” baked into the app source enough, or do I need to set up generations of such “handshake” keys dynamically somehow?

The server by itself doesn’t have access to any sensitive data, so even if the user hits some private endpoints, it won’t get them anywhere, but I just want those to be hidden from the public. Basically, I want to ignore all requests hitting particular routes, unless they are coming from my iOS app.

The server component runs on RoR, if that’s important.

Best Answer

You cannot effectively reject connections unless you supply every customer with a private key which you can individually revoke. But this is probably overkill. You don't need a bulletproof solution if most people won't bother to fire a bullet.

It's a security question, so let's describe a threat model and mitigation strategies.

Suppose you have an URL hitting which can incur noticeable cost to you (e.g. processing cost), and you want to protect it from both a simple DoS attack and from copycat apps.

Use SSL to hide the connection from being easily analyzed. Use a non-obviuos port number, a redirect sequence, a cookie exchange to complicate the connection slightly before you do the costly part of the request. Use some secret code baked into your app to let the server know it has to accept the connection.

Now someone cannot learn the expensive-to-hit URL simply by running a packet sniffer, or by looking at URL-like strings in your code. A potential attacker has to decompile your app.

You cannot really protect your code from being decompiled and / or run under a debugger. The attacker eventually learns the secret key and the connection sequence.

You notice that you start to receive rouge requests at your costly URL: either in a form of an attack, or in a form of a copycat app that has to access your service in order to run, or maybe an exploit code is publicly posted. You cannot tell a rogue request from a legitimate request, though.

Create a free minor update to your app, with a different secret key. It should hit a different costly URL that serves the same data as the compromised costly URL. For some time, make the both URLs accessible.

Watch your user base switch to the updated version. Throttle the compromised costly URL and eventually 404 it. You have just mitigated a security breach, hopefully without losing too much. Back to square one.

Disclaimer: I'm not a security expert.

Related Topic