Passing app id(bundle id on iOS or package name in android) to backend API

I want to make sure that my backend api are accessed by my app only.

I have noticed that on android when we make a api call it passing header ‘X-Requested-With’ which contains app id. So I can check on serve side and filter request based on that.

But iOS doesnt pass this header. Is there any way to configure to always pass this header?

You could manually append that information to the header before making the requests. Look in the Angular documentation for the details.

i tried that. But its not sending that header on iOS.

if you are doing a POST, then you can send your app id as a data parameter and read it on the server for validation

I dont want to set it manually. My purpose was if app sends it on its own then i can trust that value on service side and reject request having value other than my app bundle id.

And on android it sends bundle id as X-Requested-With without any kind of configuration, its just iOS is not passing that header.

My purpose is that only genuine app should be able to talk to my api.

Ok, Have you tried this and its not working?

.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.headers.common['X-Requested-With'] = 'app_id';
}]);
  1. Make sure you’re using HTTPS, not HTTP. Many mysterious failures have been occurring recently on iOS due to this.

  2. What you’re attempting to do isn’t really possible. Anybody sufficiently motivated could extract any hardcoded authentication credential out of your app binary and spoof it using a different client.

@rapropos So there is no way to make sure only genuine app is talking to api?

My App is open and doesnt need any login. But I dont want to keep my API open and wanted to have some mechanism so that only my app can talk to them. Understood all key will be easily extracted from cordova based JS application and anybody can generate request from postman.

But at least is there way to make sure that no one can use API from their application/website? Thats where i was going on route of passing app package name (bundle id on iOS) and server checks that. But some reason iOS doesnt pass any bundle ID to api.

Whats the type of server on which your api is hosted?

Not using a shared hardcoded secret, no, and if you don’t want any sort of login in the app, this is going to be quite a challenge, because you won’t have any sort of backend concept of “authorized user”. Typically one would use a long-lived server-issued JWT here, which the app could put into device storage and reuse.

There a typical attack vector would be a stolen device or rogue user publishing their token. At least in that situation you can identify where the token came from (it would be in the claims), which may act as a deterrent against rogue users and would also allow you to selectively revoke tokens issued before a certain time on a certain account. However, this requires having a backend user concept.

@rapropos Thanks for update.

So all cordova based app which doesnt require any login, keep their api open or compromise on security?

@thesourav I have asp.net web api based backend.

Cordova apps or any web based apps are just clients, the authentication is the responsibility of the server. You have to keep a list of registered users and implement oauth( which is the simplest ) to restrict access.
Asp.net web api has a very well implemented capability of oauth.

I don’t think it’s cordova-specific. Native apps are in the same boat. If the server is looking for a specific string in a specific header, and that string is available in the app binary (which it must be in order for the app to send it), anybody sufficiently knowledgeable and motivated can extract it and pretend to be the “genuine app” as a client.

Now I guess you could use a different protocol here instead of HTTP, but that is a pretty daunting task. TLS client authentication is a massive PITA, much more of a hassle for users than a typical signup process (which you apparently don’t even want to impose).

You could put rate limits by IP address, I suppose, if you wanted to stop wholesale usage, but pretty much anything else I can think of is going to be strictly on the server side, having nothing to do with communication between the app and the API itself. Sorry to be the bearer of bad news.

thanks @rapropos

I would not worry about this for now and take it when it becomes an issue.