views:

1437

answers:

11

I am developing an iPhone app together with web services. The iPhone app will use GET or POST to retrieve data from the web services such as http://www.myserver.com/api/top10songs.json to get data for top ten songs for example.

There is no user account and password for the iPhone app. What is the best practice to ensure that only my iPhone app have access to the web API http://www.myserver.com/api/top10songs.json? iPhone SDK's UIDevice uniqueueIdentifier is not sufficient as anyone can fake the device id as parameter making the API call using wget, curl or web browsers.

The web services API will not be published. The data of the web services is not secret and private, I just want to prevent abuse as there are also API to write some data to the server such as usage log.

+3  A: 

Use some form of digital signatures in your request. While it's rather hard to make this completely tamper proof (as is anything with regard to security). It's not that hard to get it 'good enough' to prevent most abuse.

Of course this highly depends on the sensitivity of the data, if your data transactions involve million dollar transactions, you'll want it a lot more secure than some simple usage statistic logging (if it's hard enough to tamper and it will gain little to no gain to the attacker except piss you of, it's safe to assume people won't bother...)

Pieter
Exactly. The value of the data will indicate how much protection you'll need.
bbrown
A: 

A very cheap way to do this could be getting the iPhone software to send extra data with the query, such as a long password string so that someone can't access the feed.

Someone could reverse engineer what you have done or listen to data sent over the network to discover the password and if bandwidth limitations are the reason for doing this, then a simple password should be good enough.

Of course this method has it's problems and certificate based authentication will actually be secure, although it will be harder to code.

Brock Woolf
A: 

The problem with most if not all solutions here is that they are rather prone to breaking once you add proxies in the mix. If a proxy connects to your webservice, is that OK? After all, it is probably doing so on behalf of an iPhone somewhere - perhaps in China? And if it's OK for a proxy to impersonate an iPhone, then how do you determine which impersonations are OK?

MSalters
A proxy should send all data to the server that the iPhone sent to the proxy, so I don't see a problem.
Herms
+4  A: 

What you can do is get a secret key that only you know, Include that in an md5 hashed signature, typically you can structure signatures as a s tring of your parameters a nd values and the secret appended at the end, then take the md5 hash of that...Do this both in your client and service side and match the signature string, only if the signatures match do you get granted access...Since t he secret is only present i n the signature it w ill be hard to reverse engineer and crack..

Daniel
how would that be difficult to crack? You just read the HTTP request and read the md5 value of your parameter?
erotsppa
well if u sniff the http request and resend it just like that sure youll get some response, but no one will be able to generate their own requests because they will not know the secret
Daniel
To get past that, one can just use some transport level security so when sniffed the data will be encrypted
Daniel
A: 

I find all the answers here that suggests a secret key/password quite ridiculous. It takes 3 minutes to run a tcp sniffing program and launch your iphone app, then your whole HTTP request is shown including your "secret" token.

erotsppa
Only if the entire secret is sent over the wire. If there's a shared secret that only the server and client knows, and it uses that to generate something to send over the wire (in a way that can't be reversed) then it would work fine. Daniel's suggestion seems to go that route.
Herms
As herms commented...Also you can use some transport security to prevent a sniffer from getting the actual text request going through the wire
Daniel
+1  A: 

The most secure solution is probably a digital signature on the request. You can keep a secret key inside the iPhone app, and use it to sign the requests, which you can then verify on the server side. This avoids sending the key/password to the server, which would allow someone to capture it with a network sniffer.

A simple solution might be just to use HTTPS - keeping the contents of your messages secure despite the presence of potential eavesdroppers is the whole point of HTTPS. I'm not sure if you can do self-signed certificates with the standard NSURLConnection stuff, but if you have a server-side certificate, you're at least protected from eavesdropping. And it's a lot less code for you to write (actually, none).

I suppose if you use HTTPS as your only security, then you're potentially open to someone guessing the URL. If that's a concern, adding just about any kind of parameter validation to the web service will take care of that.

Mark Bessey
+1  A: 

Here's an expansion on Daniel's suggestion.

Have some shared secret that the server and client know. Say some long random string.

Then, when the client connects, have the client generate another random string, append that to the end of the shared string, then calculate the MD5 hash.

Send both the randomly generated string and the hash as parameters in the request. The server knows the secret string, so it can generate a hash of its own and make sure it matches the one it received from the client.

It's not completely secure, as someone could decompile your app to determine the secret string, but it's probably the best you'll get without a lot of extra work.

Herms
Herms, can you give an example of how you would send the request? From what I understand, you are sending the md5(secretkey+anotherrandom) over the network? Couldn't someone just un-md5 that request and read the secretkey straight out?
erotsppa
There's no "un-md5" possible as it's a one-way hashing algorithm. The best they could do (on this front) is hash a string and look for a collision (using so-called "rainbow tables"). But the randomness plus the secret key makes a "rainbow table" attack prohibitive.
bbrown
bbrown is correct. MD5 is a one-way hash, so you don't have to worry about someone decrypting it to figure out the secret.
Herms
A: 

I asked an Apple security engineer about this at WWDC and he said that there is no unassailable way to accomplish this. The best you can do is to make it not worth the effort involved.

I also asked him about possibly using push notifications as a means of doing this and he thought it was a very good idea. The basic idea is that the first access would trigger a push notification in your server that would be sent to the user's iPhone. Since your application is open, it would call into the application:didReceiveRemoteNotification: method and deliver a payload of your own choosing. If you make that payload a nonce, then your application can send the nonce on the next request and you've completed the circle.

You can store the UDID after that and discard any requests bearing unverified UDIDs. As far as brute-force guessing of necessary parameters, you should be implementing a rate-limiting algorithm no matter what.

bbrown
If push notifications aren't your thing, then the only other course of action that I've come across that raises the bar sufficiently is a key exchange. Look at the CryptoExercise sample app to find out how to generate a random symmetric key on the iPhone and use a public key to encrypt it and send it to another iPhone. It's not perfect, but used in conjunction with other countermeasures and you've got some hope of protecting your assets.
bbrown
A: 

Have some kind of key that changes every 5 minutes based on an algorithm which uses the current time (GMT). Always allow the last two keys in. This isn't perfect, of course, but it keeps the target moving, and you can combine it with other strategies and tactics.

I assume you just want to dissuade use of your service. Obviously you haven't set up your app to be secure.

Nosredna
A: 

please email me at [email protected] have a similar issue

mars
A: 

I would assume someone can decompile your distribution and access any embedded 'secret'; one just has to look at whats going on in the iPhone 'jailbreak' community to see that anything put in the hands of hackers, is hackable.

Neil