1

I have a read-only web API for use with a mobile app. There are no user logins - just searches performed against an API and a set of results returned.

NOTE: This isn't about USERs logging in as the questions I can find are about, but just one log in for the whole API, just to confirm that it is actually our iOS app accessing it, and not some Android app that somone else made and is just using our API.

I'd like only my app to be able to access the API. Even though the data is public, I don't want anyone to be able to use the API.

I was going to add a basic key check to be sent with each request, as many APIs do, a simple key=sjetow3vthw3iulbtq4wv in the request and verify it, but I understand that keys can't be securely stored in iOS apps, like at all....?

Is this impossible to achieve? Say a website like Booking.com and their iOS app - surely it can't be right that there's no protection on their API, and anyone could develop an app againt their API? Can they be secured at all?

Thanks

  • 2
    booking.com is making money from provisions of hotel bookings etc. If somebody uses their API they might actually profit from it. Situation is different for you if you are selling an app which in effect is just a portal to information you provide on the internet. – Steffen Ullrich Oct 27 '16 at 17:36
  • @SteffenUllrich Right, but Booking.com only make money when I use their booking links - if I created a mobile hotel app which just used their data API but my affiliate links I'm sure they wouldn't like it. Maybe they weren't the best example, but there are 1000s of apps like this, and I still sorta refuse to believe there's no solution! – samiles Oct 31 '16 at 8:57
  • 1
    @samiles You might be surprised at how many rely on obfuscating their API methods... I've also seen apps implement certificate pinning and jail break detection, which makes intercepting traffic harder, in turn making it take a lot more effort to find out what the API calls are in the first place. – Matthew Oct 31 '16 at 10:34
  • This is impossible, stop trying. In most cases you'll spend more money fighting this than what the "unauthorized use" will cost you. – André Borie Nov 30 '16 at 10:40
  • What is the problem that you wish to avoid? Bandwidth usage? Competitive analysis? Processor Usage? – Jeff K Feb 28 '17 at 22:47
1

Any secret you may have in a mobile app is lost to the user. You can't secure anything that is given to the client. On the other hand, a request to your API is the same from any source. The client can send anything.

Given these assumptions, it is impossible to make your API only work with your client. Anybody can extract any identifier from your client and make another app with the same identifiers or secrets to query your API, and you have no way to tell who (what piece of software) the caller is.

And from here, I think it's probably a legal question, you can create a suitable Terms of Service to prevent that and talk to lawyers what can be done to gain legal protection.

Technically the best that you can do is probably using API keys, so even if you don't want to identify individual users, you could still have them create API keys for themselves to connect to your API. This way, you could at least control and possibly ban API keys that you think are against your ToS, and you could also deny issuing a new API key to offending users. But for this you would also need facilities to actually try and find out who those users are (which API keys, technically), and that will not be exact science.

  • If clients generate their own API key then how will you authenticate them that those API keys are indeed correct? – defalt Apr 30 '17 at 8:45
  • @defalt sorry for the confusion. :) The application would of course generate API keys. What I meant by users doing it for themselves was that there could be a UI for users to have the application create an API key for them whenever they need a new one. – Gabor Lengyel Apr 30 '17 at 8:50
  • If application would create its own API key then unauthorized client can also use that key to access your API from his own android app. Another way is if application server generates API key for clients and sends it to each client which has to be used for every API call. Nowadays using API key+JWT is considered more secure because the JWT signature is not known to anyone except the application server which generates it. – defalt Apr 30 '17 at 9:01
  • 1
    Exactly, I was talking about that. If you store the API key on the client, it is lost to anyone wanting to use it. I was saying "it is impossible to make your API only work with your client". You can at least create an opportunity for yourself to deny some issued API keys and also deny some users trying to issue new keys for themselves. But if clients (ie. mobile apps) hold the key, this is not a form of authentication of the user or app, it may only protect against things like DoS if you use it wisely. Exactly how the key is delivered (session mgmt, JWT or else) is a totally different issue – Gabor Lengyel Apr 30 '17 at 9:12
0

What you would need a way to store some secrets at the client in a way that the client can neither misuse nor copy these. These secrets are then used to sign the messages so that you know that it comes from a trusted client.

There are ways to do this with protected tamper resistant hardware like smart cards or dongles. There is no way to do this in software only as long as the user has as at least as much control over the system as the application which is the case with jail broken phones etc. Because, whatever the application does the user could do too within its own application by replicating the behavior.

This means unless you ship special hardware to each user your only choice will be to try limited protection by obfuscating the code and protect it a bit against reverse engineering.

0

There is no way to identify an application, because it would require a secret that only the application knows. But once it is in the code or in a data file of the application, it is vulnerable to reverse engeneering. The only protection you have is only obfuscation, and we all know that security by obfuscation is er... not secure.

If you really want to protect your API without too much bothering your users with passwords, give a unique id to every legitimate user of your application and authenticate them through an asymetric key. This is the best you can do, and all browser on any platform have provision for managing client certificates in a way that is transparent for the user.

  • what do you mean by "authenticate them through an asymetric key" here? – devedv Mar 5 at 15:09
  • @devedv: asymetric keys is the base of ssh key authentication, or X509 client certificate authentication. What I meant was use client certificates. – Serge Ballesta Mar 5 at 15:37
  • oh that can be easily retrieved from the mobile application. I can't use that approach. – devedv Mar 5 at 15:40
  • @devedv: In client cert authentication, the client application never knows the private key. It receives a unique token from the server, asks the system to sign it with the private key (only known to the underlying system) and sends it back to server which can control the signature with the public key. It is used (not in mobile applications) with smartcards or HSM. It could be made available for mobile devices with the TPM 2.0 Mobile architecture – Serge Ballesta Mar 5 at 15:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.