tags:

views:

350

answers:

5

Hi All,

I'm developing an app which connects to an XML based API. I have control over both the server and the app - is there any way I can make sure only my app can access the API?

There is no user authentication.

Thanks,

David

EDIT:

The main concern is that bots steal data by scanning the XML.

How about this:

I request a session with the device UDID and I get a handshake key.

23354

from this string a password is calculated on both the server and the client according to an agreed algorithm (it just has to be hard to reconstruct)

Let's say for now that I add 1 to the handshake key

password = 23354

On all API calls I then pass this password along with the UDID. This would allow the server to limit each session to a certain number of calls, no?

What do you think?

+2  A: 

You can provide a quick challenge response mechanism, assuming you have control over the XML api.

Generate a number and include it in your app and on the server side. Use that as a seed to srand() on both client and server.

Have the request from the client include something like:

<handshake id="123">12312931</handshake>

there id means the 123'rd generated random number and 12312931 is the value after calling rand() 123 times. The value 123 should be a randomly generated number (generated with a different seed!) as well.

This isn't a fool proof challenge response, but it's simple and efficient, and doesn't rely on anything more than a basic ANSI C library set.

Note that it's not terribly secure, either - all one would have to do is have your client challenge their own server, then generate the (in this example) 123'rd random number for every seed value until they find it. So I wouldn't use this expecting it to provide cryptographic level authentication or access control. It just provides a simple non-trivial challenge response that is efficient and simple to implement.

groundhog
I don't believe there's any promise that the sequence returned by rand() be the same from platform to platform. POSIX doesn't seem to define the actual algorithm, just the minimum requirements. I assume in the above the server chooses "123". If the client chooses it, then this provides no security at all (not even trivial security). If the server does send id, there are faster breaks than calculating all values for 64k seeds. Most obvious is to MiM the session. I can also find the seed much more quickly by challenging the client with id=1, then id=2 for the few collisions.
Rob Napier
A: 

Hello,

Access your web service via https with authentication.

thierryb
Yes, but how? Trying to figure that out on iPhone. What classes are you using for this?
Spanky
+2  A: 

No, it is not possible to really ensure that only your app can contact your server. There are obfuscation techniques for raising the bar somewhat on attackers, and those will work for most attackers. Your underlying problem is not solvable for a dedicated attacker. You can find a list of other posts on this subject at iPhone: How to encrypt a string. There are several techniques you can use in those posts, and some discussion of how and whether you should attack the underlying issues.

Rob Napier
A: 

You can use some sort of signature in order to verify that it is indeed your app making the call, you calculate the signature both server side and app side, only if they match will the service return with a response to the request. Typically signatures are composed of some s ort of parameters of your function followed by a secret key, then take the md5 hash of that and sned it through. In the r equest no one will be able to find the secret key because it is in the md5 hash.

Daniel
Unfortunately the secret key has to then be encoded in your program, which you then must give to the users. An attacker will reverse engineer the secret key out of the executable (or out of memory in a debugger) and will then use it to connect to the server. Or he will modify your program to do what he wishes, and let your program handle the secret handshake for him. This is a form of obfuscation, but it will not solve the problem if you have any kind of dedicated attacker.
Rob Napier
A: 

I think the real question you need to ask is how much is your data at risk of attack. I'd say 99% of the time you'll be fine with just an obfuscated URL that will be hard to guess, since chances of the average user trying to do anything with it outside your app are slim. If you're worried about competitors stealing from you, I'd suggest something a little more nefarious:

In your app, set it up so that your app and server change URLs every so often, maybe every two weeks. Then if someone does attempt to access your XML API, they'll be fighting a constant battle of figuring out your URLs. And as icing on the cake, keep the old URLs active but have them return bad data. I think you can let your imagination run and figure out the rest from here.

Gordon Worley
How does the app determine what the correct URL will be? Whatever technique it uses can be duplicated by anyone who reverse engineers the app. Similarly, simply sniffing the traffic of the legitimate app will tell the rogue app where to connect. This solution is complicated to implement without impacting legitimate users (who may have trouble during each transition), but is just another version of a shared secret, except this secret isn't even encrypted on the wire (since the URL can't be).
Rob Napier