Identify mobile application - authentication

Is it possible to identify (authenticate) a mobile application HTTP request ?
for example a request from a web server can by identified by the domain or IP, assuming I know from where it should come from I can accept the request or deny if it came from an unexpected origin.
doe's mobile application has some sort of unique id (that cannot be mimicked)?

If you need to make secure HTTP calls (webservice API) from a mobile app (a native compiled app), you can try the following approach:
Edit: This approach assumes that you can't rely on the user operating the app for authentication purposes (because then you could simply ask the user to type in a secure password in the app).
Assuming you are implementing the app, save some sort of secret API key in the code.
When the app makes an API call via HTTP, it will always be done using HTTPS (so everything is encrypted).
The app will send the secret API key as a URL parameter.
The server will authenticate by checking if the secret key is correct.
Sniffing the app traffic will not reveal the secret key (because of the HTTPS).
You are mostly vulnerable to someone reverse-engineering your app to discover the secret key inside. This can be made tough by using various obfuscation and anti-debugging techniques, but cannot be made truly impossible. As long as you're using a compiled language (like Objective-C, not JS for a web-app) this will already be tough without any special games. If you avoid placing your API key string as-is and compute it using some short code in the app, you've made it about 1000 times tougher to discover.
Without knowing more about your specific problem, it's hard to suggest alternate approaches. Please give more details if you are looking for something different.

There are two methods used in practice. HTTP basic authentication (not much secure for mobile apps) and OAuth2 (secured compared to HTTP basic authentication).
HTTP Basic Authentication: The process is simple for both technical writers of API services, and also developers using them:
A developer is given an API key (typically an ID and Secret). This API key usually looks something like this: 3bb743bbd45d4eb8ae31e16b9f83c9ba:ffb7d6369eb84580ad2e52ca3fc06c9d.
He is responsible for storing API key in a secure place on their server, so that no one can access it. He makes API requests to the API service by feeding the API key in the HTTP Authorization header along with the word 'Basic' (which is used by the API server to properly decode the authorization credentials). The key is also Base64 encoded.
For example key could be: 3bb743bbd45d4eb8ae31e16b9f83c9ba:ffb7d6369eb84580ad2e52ca3fc06c9d
encoded in base64: M2JiNzQzYmJkNDVkNGViOGFlMzFlMTZiOWY4M2M5YmE6ZmZiN2Q2MzY5ZWI4NDU4MGFkMmU1MmNhM2ZjMDZjOWQ=.
The API server reverses this process. When it finds the HTTP Authorization header, it will decode base64 result, read the API key ID and Secret and validate these tokens before allowing the request to be processed.
HTTP Basic Authentication is simple but for mobile apps securing the API Key is a main concern. HTTP Basic Authentication requires raw API keys to be sent over the wire for each request, thereby increasing chances of misuse in the long run.
Also it is impractical as you cannot safely embed API keys into a mobile app that is distributed to many users.
For instance, if you build a mobile app with your API keys embedded inside of it, a user could reverse engineer your app, exposing this API key, and abusing your service.
So HTTP Basic Authentication risky in open environments, like web browsers and mobile applications.
NOTE: Like all authentication protocols, HTTP Basic Authentication must be used over SSL at all times.
OAuth2 for Mobile API Security:
 OAuth2 is an excellent protocol for securing API services from open devices, and provides a better way to authenticate mobile users via token authentication.
OAuth2 token authentication works from a user perspective (OAuth2 name it password grant flow):
When a user starts the mobile app he is prompted for username or email and password.
The developer sends a POST request from app to API service with the login data included (over SSL). Then validate the user credentials, and create access token for the user which expires after a certain amount of time. This access token can be stored on mobile device, treating it like an API key which allows access to API service. When the access token expires user is prompted again for login details.
OAuth2 generates access tokens that can be stored in an open environment temporarily and are secure. It is secure because the access token are generated for temporary purpose and it reduces damage potential.
The token is stored according to the mobile platform used. For Android app, access tokens can be stored in Shared Preferences and for iOS app, in the Keychain.

It depends on how you define "mobile application". Any application running on a mobile device ? Web browsing running on a mobile device ? What is a mobile device to you ?
Anyways, the general short answer, is that you can detect the device type using the User-Agent sent in the HTTP headers. All popular mobile browsers sends this. But be aware, that:
It can be spoofed (easily)
Some applications (ie iPhone or Android apps and similar) can be written in such a way, that they don't send a user agent with the HTTP requests. Best practice mandates to send the User-Agent though.
I don't know of a more reliable way to do this; and as long as stuff happens over HTTP there generally won't be any way of knowing anything about the client for certain. For mostly all the use cases, you will be alright with looking at the User-Agent.
You can buy access to User-Agent databases containing various device data, if applicable, two of such being WURFL or DeviceAtlas.

Related

Storing api keys

I am using the Goodreads api to get book data for my react native app. I have to use a key for using the api. Is it OK for me to store the api key on the app itself or should I put the key on a server that redirects all the data to the app?
Is it OK for me to store the api key on the app itself
No, because as I demonstrate in the article How to Extract an API Key from a Mobile App by Static binary analysis it can be extracted with the help of several open source tools, like by using the Mobile Security Framework, but you can also grab the API key with a MitM attack, as I show in the article Steal that API Key with a Man in the Middle Attack, that uses the open source tool MiTM Proxy.
If you leave a third party API key in the mobile app, then they are up for grabs from attackers, and when they start using it without your knowledge your bill in the third party provider may go through the roof before you acknowledge that something is wrong, and on that time the only solution is to revoke the API key, thus shutting down the use of the mobile app, and if you make a new release of your mobile app with a new API key it will be just a matter of hours until the attacker come back and steal the API key again.
or should I put the key on a server that redirects all the data to the app?
Yes, and this is a good approach, because now you have only one place to store and protect all third part API keys. This have the benefit to let you control and throttle the use of them as you see fit.
With this solution you still need an API key in your mobile app to allow access to your API server, but while you continue vulnerable for attackers to steal it, you are now in direct control of throttling the access to your API server and if you identify in each access the WHO and the WHAT is accessing the API server, then you have a more fine grade control, but attacker will continue to be able to slip between all our defenses, because is very hard to know WHAT is accessing the API server.
You may be thinking by now... do you mind to explain the WHO vs the WHAT?
The Difference Between WHO and WHAT is Accessing the API Server
To better understand the differences between the WHO and the WHAT are accessing an API server, let’s use this picture:
The Intended Communication Channel represents the mobile app being used as you expected, by a legit user without any malicious intentions, using an untampered version of the mobile app, and communicating directly with the API server without being man in the middle attacked.
The actual channel may represent several different scenarios, like a legit user with malicious intentions that may be using a repackaged version of the mobile app, a hacker using the genuine version of the mobile app, while man in the middle attacking it, to understand how the communication between the mobile app and the API server is being done in order to be able to automate attacks against your API. Many other scenarios are possible, but we will not enumerate each one here.
I hope that by now you may already have a clue why the WHO and the WHAT are not the same, but if not it will become clear in a moment.
The WHO is the user of the mobile app that we can authenticate, authorize and identify in several ways, like using OpenID Connect or OAUTH2 flows.
OAUTH
Generally, OAuth provides to clients a "secure delegated access" to server resources on behalf of a resource owner. It specifies a process for resource owners to authorize third-party access to their server resources without sharing their credentials. Designed specifically to work with Hypertext Transfer Protocol (HTTP), OAuth essentially allows access tokens to be issued to third-party clients by an authorization server, with the approval of the resource owner. The third party then uses the access token to access the protected resources hosted by the resource server.
OpenID Connect
OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. It allows Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner.
While user authentication may let the API server know WHO is using the API, it cannot guarantee that the requests have originated from WHAT you expect, the original version of the mobile app.
Now we need a way to identify WHAT is calling the API server, and here things become more tricky than most developers may think. The WHAT is the thing making the request to the API server. Is it really a genuine instance of the mobile app, or is a bot, an automated script or an attacker manually poking around with the API server, using a tool like Postman?
For your surprise you may end up discovering that It can be one of the legit users using a repackaged version of the mobile app or an automated script that is trying to gamify and take advantage of the service provided by the application.
Well, to identify the WHAT, developers tend to resort to an API key that usually they hard-code in the code of their mobile app. Some developers go the extra mile and compute the key at run-time in the mobile app, thus it becomes a runtime secret as opposed to the former approach when a static secret is embedded in the code.
The above write-up was extracted from an article I wrote, entitled WHY DOES YOUR MOBILE APP NEED AN API KEY?, and that you can read in full here, that is the first article in a series of articles about API keys.
Your problem is not solved yet
Now that you know the difference between WHO and WHAT is accessing your API server you must have realized that your API server is still vulnerable to be abused by attackers.
You can resort now to employ several layers of defense, starting with reCaptcha V3, followed by Web Application Firewall(WAF) and finally if you can afford it a User Behavior Analytics(UBA) solution.
Google reCAPTCHA V3:
reCAPTCHA is a free service that protects your website from spam and abuse. reCAPTCHA uses an advanced risk analysis engine and adaptive challenges to keep automated software from engaging in abusive activities on your site. It does this while letting your valid users pass through with ease.
...helps you detect abusive traffic on your website without any user friction. It returns a score based on the interactions with your website and provides you more flexibility to take appropriate actions.
WAF - Web Application Firewall:
A web application firewall (or WAF) filters, monitors, and blocks HTTP traffic to and from a web application. A WAF is differentiated from a regular firewall in that a WAF is able to filter the content of specific web applications while regular firewalls serve as a safety gate between servers. By inspecting HTTP traffic, it can prevent attacks stemming from web application security flaws, such as SQL injection, cross-site scripting (XSS), file inclusion, and security misconfigurations.
UBA - User Behavior Analytics:
User behavior analytics (UBA) as defined by Gartner is a cybersecurity process about detection of insider threats, targeted attacks, and financial fraud. UBA solutions look at patterns of human behavior, and then apply algorithms and statistical analysis to detect meaningful anomalies from those patterns—anomalies that indicate potential threats. Instead of tracking devices or security events, UBA tracks a system's users. Big data platforms like Apache Hadoop are increasing UBA functionality by allowing them to analyze petabytes worth of data to detect insider threats and advanced persistent threats.
All this solutions work based on a negative identification model, by other words they try their best to differentiate the bad from the good by identifying what is bad, not what is good, thus they are prone to false positives, despite of the advanced technology used by some of them, like machine learning and artificial intelligence.
So you may find yourself more often than not in having to relax how you block the access to the API server in order to not affect the good users. This also means that this solutions require constant monitoring to validate that the false positives are not blocking your legit users and that at same time they are properly keeping at bay the unauthorized ones.
Regarding APIs serving mobile apps a positive identification model can be used by using a Mobile App Attestation solution that guarantees to the API server that the requests can be trusted without the possibility of false positives.
Mobile App Attestation
Use a Mobile App Attestation solution to enable the API server to know is receiving only requests from a genuine mobile app.
The role of a Mobile App Attestation service is to guarantee at run-time that your mobile app was not tampered or is not running in a rooted device by running a SDK in the background that will communicate with a service running in the cloud to attest the integrity of the mobile app and device is running on.
On successful attestation of the mobile app integrity a short time lived JWT token is issued and signed with a secret that only the API server and the Mobile App Attestation service in the cloud are aware. In the case of failure on the mobile app attestation the JWT token is signed with a secret that the API server does not know.
Now the App must sent with every API call the JWT token in the headers of the request. This will allow the API server to only serve requests when it can verify the signature and expiration time in the JWT token and refuse them when it fails the verification.
Once the secret used by the Mobile App Attestation service is not known by the mobile app, is not possible to reverse engineer it at run-time even when the App is tampered, running in a rooted device or communicating over a connection that is being the target of a Man in the Middle Attack.
The Mobile App Attestation service already exists as a SAAS solution at Approov(I work here) that provides SDKs for several platforms, including iOS, Android, React Native and others. The integration will also need a small check in the API server code to verify the JWT token issued by the cloud service. This check is necessary for the API server to be able to decide what requests to serve and what ones to deny.
Summary
Anything that runs on the client side and needs some secret to access an API can be abused in different ways and you must delegate the access to all third part APIs to a backend under your control, so that you reduce the attack surface, and at the same time protect their secrets from public pry eyes.
In the end, the solution to use in order to protect your API server must be chosen in accordance with the value of what you are trying to protect and the legal requirements for that type of data, like the GDPR regulations in Europe.
For react native use react-native-config library. While using this library you can secure your api keys as well as you can save more secret keys which use in the native code. Like we can save onesignal, codepush etc keys.
https://github.com/luggit/react-native-config
Store them in a .env file like this API_KEY=yourKey.
Install npm package react-native-dotenv.
Then import to to files as needed with react-native-dotenv package;
import { API_KEY } from 'react-native-dotenv'
The .env file should never be committed to Github.

ASP.NET MVC Web API Authentication Token Security Issues

I am developing a asp.net mvc project with Web API. Web API will be consumed by Website, mobile apps and third party. Now, on some APIs will be called on Home page only without any login and same APIs will be called after login only.
Now, considering my website scenario, I have called APIs from AngularJs. We called an api which will generate a token on session_start. Then from NG we called a mvc controller method which will simply get that token and then the token will passed in HTTP-Header in All requests.
On API side, we fetch the token, decrypt it and show result.
Problem is, when I see Google Chrome's Network Tab (press F12) I can easily see API Calls and even Token in headers. I feel security vulnerability. For Open APIs, we thought of having some expiry time and request counts. But some APIs will be sensitive, like adding data in DB(POST APIs, based on data passed as parameters) and they also will be available to Guest Users. We don't want someone to misuse it and do harmful things.
How can we achieve maximum security in this scenario? What will be ideal security process?
To further explain Marco Sandrini's comment...
The security does not rely on hiding the API structure (method names, data format, etc...), but on giving access to those APIs only to authorized clients, which is what your tokens should do. In other words if your tokens are cryptographically sound (cannot be spoofed or faked), your connection is protected (nobody can intercept your tokens) and your backend correctly authenticates and authorizes your clients, you should be fine.
The token should not be subject to replay attacks. The server should already be expecting a different permutation of the token for subsequent requests, and you shouldn't know how to produce that by reading the token.
Proper SSL/TLS will protect the content of the connection from prying eyes. If your guest users can see other's sensitive information in their Chrome network tab, then you should worry because something has gone wrong with your implementation strategy.

REST API authentication for web app and mobile app

I'm having some trouble deciding how to implement authentication for a RESTful API that will be secure for consumption by both a web app and a mobile app.
Firstly, I thought to investigate HTTP Basic Authentication over HTTPS as an option. It would work well for a mobile app, where the username and password could be stored in the OS keychain securely and couldn't be intercepted in transit since the request would be over HTTPS. It's also elegant for the API since it'll be completely stateless. The problem with this is for the web app. There won't be access to such a keychain for storing the username and password, so I would need to use a cookie or localStorage, but then I'm storing the user's private details in a readily accessible place.
After more research, I found a lot of talk about HMAC authentication. The problem I see with this approach is there needs to be a shared secret that only the client and server knows. How can I get this per-user secret to a particular user in the web app, unless I have an api/login endpoint which takes username/password and gives the secret back to store in a cookie? to use in future requests. This is introducing state to the API however.
To throw another spanner into the works, I'd like to be able to restrict the API to certain applications (or, to be able to block certain apps from using the API). I can't see how this would be possible with the web app being completely public.
I don't really want to implement OAuth. It's probably overkill for my needs.
I feel as though I might not be understanding HMAC fully, so I'd welcome an explanation and how I could implement it securely with a web app and a mobile app.
Update
I ended up using HTTP Basic Auth, however instead of providing the actual username and password every request, an endpoint was implemented to exchange the username and password for an access key which is then provided for every authenticated request. Eliminates the problem of storing the username and password in the browser, but of course you could still fish out the token if you had access to the machine and use it. In hindsight, I would probably have looked at OAuth further, but it's pretty complicated for beginners.
You should use OAuth2. Here is how:
1) Mobile App
The mobile app store client credentials as you state yourself. It then uses "Resource Owner Password Credentials Grant" (see https://www.rfc-editor.org/rfc/rfc6749#section-4.3) to send those credentials. In turn it gets a (bearer) token it can use in the following requests.
2) Web site
The website uses "Authorization Code Grant" (see https://www.rfc-editor.org/rfc/rfc6749#section-4.1):
Website sees unauthorized request and redirects browser to HTML-enabled autorization endpoint in the REST api.
User authenticates with REST service
REST site redirects user back to website with access token in URL.
Website calls REST site and swaps access token to authorization token.
Here after the website uses the authorization token for accessing the REST service (on behalf of the end-user) - usually by including the token as a "bearer" token in the HTTP Authorization header.
It is not rocket science but it does take some time to understand completely.
3) Restricting API access for certain applications
In OAuth2 each client is issued a client ID and client secret (here "client" is your mobile app or website). The client must send these credentials when authorizing. Your REST service can use this to validate the calling client
I resolved this for my own API quite easily and securely without the need to expose any client credentials.
I also split the problem into 2 parts. API authentication - is this a valid request from a recognised entity (website or native app). API authorisation, is that entity allowed to use this particular endpoint and HTTP verb.
Authorisation is coded into the API using an access control list and user permissions and settings that are set up within the API code, configuration and database as required. A simple if statement in the API can test for authorisation and return the appropriate response (not authorised or the results of processing the API call).
Authentication is now just about checking to see if the call is genuine. To do this I issue self signed certificates to clients. A call to the API is made from their server whenever they want - typically when they generate their first page (or when they are performing their own app login checks). This call uses the certificates I have previously provided. If on my side I am happy the certificate is valid I can return a nonce and a time limited generated API key. This key is used in all subsequent calls to other API endpoints, in the bearer header for example, and it can be stored quite openly in an HTML form field or javascript variable or a variable within an app.
The nonce will prevent replay attacks and the API key can be stolen if someone wants - they will not be able to continue using after it expires or if the nonce changes before they make the next call.
Each API response will contain the next nonce of if the nonce doesn't match it will return an authentication error. In fact of the nonce doesn't match I kill the API key too. This will then force a genuine API user to reauthenticate using the certificates.
As long as the end user keeps those certificates safe and doesn't expose the method they use to make the initial authentication call (like making it an ajax request that can be replayed) then the API's are nice and secure.
One way of addressing the issue of user authentication to the API is by requesting an authentication token from the API when the user logs in. This token can then be used for subsequent requests. You've already touched on this approach - it's pretty sound.
With respect to restricting certain web apps. You'll want to have each web app identify itself with each request and have this authentication carried out inside your API implementation. Pretty straight forward.

“Shared” authentication for website and RESTful API

Goal: My server needs to direct non-users to a landing/home page, and logged in users to the actual app. When the app is loaded, it will make authenticated HTTP requests to a RESTful API (via Ajax).
I have a RESTful API that needs authentication. On another server I have my website, which also needs authentication, so I can determine whether to display the landing/home page for non-users or the app for logged in users.
Initially I thought it would be enough to implement HTTP Basic Auth for the RESTful API. However, in order to get authentication running for my website too, I would also need to setup authentication there, which would mean duplicating the low-level code to check the credentials in the database in both the REST API and the website servers.
Alternatively, I wondered if the website could authenticate via the RESTful API. For example, in my request handler for POST /login, I could make a GET request to my API, passing along the user credentials from the request body. If the request returns 200 OK, I could sign the user’s session, thus authenticating them. From there onwards, the Ajax requests to the REST API need to be authenticated with the same credentials, so I could:
set a cookie containing the credentials, thus allowing the JavaScript to retrieve the credentials before doing the request (OK with SSL?)
dump the credentials in the served HTML for the web app thus allowing the JavaScript to retrieve the credentials before doing the request (OK with SSL?)
proxy the API through the web app server, where I could retrieve the credentials from the session and add them to the Authorization header of the proxied request?
Alternatively, I imagine I could just share a session between the two servers, although I’ve heard that’s bad practice for RESTful design.
What would be wrong with doing it like this? Is there a better way to meet my goal?
I recently implemented something similar to this (assuming I understand you correctly), and there seemed to be a few viable options.
Have the server side of your web-app always authenticate with a specific username/password when accessing the REST API, ensuring that your web-app is always trusted and assuming that users are properly logged in on the web-app if a request is authenticated as the app.
Pros: Easy to implement, easy to understand, easy to extend for other applications as well (we had a CLI that accessed the same REST API as well).
Cons: It's impossible for the REST API to know which user is actually accessing it. If a trusted client is compromised the whole system is compromised.
Have the server side of your web-app keep user details in the session and authenticate using the users credentials every time you access the REST API.
Pros: Fairly easy to implement (although some authentication mechanisms make it hard to keep hold of the user password - for good reason). The whole procedure is transparent to the REST API.
Cons: You're now storing (for all intents and purposes in clear-text) the username and password of a user in the session of the web-server - one of the most prime targets for attack in the system.
Create an authentication system on the REST API that authenticates a request with a username/password authorization and returns a token that is valid for a limited time.
Pros: More secure, if your web-app is compromised you're not providing the attacker with your users username/passwords, but instead only allowing them a limited time access.
Cons: Much harder to implement. You might need to deal with token timeouts specifically. For purists it also means that your REST implementation (or at least the authentication system) will be arguably "stateful".
What you should implement would depend on your situation. Personally I'd definitely go with the more secure option (the last one), but due to external constraints we were forced to implement the first option in our specific case (with the promise we'd revisit it and upgrade later - unfortunately later never comes).
I think your approach with using Basic HTTP Authentication in REST service and having your app authenticate with the service is perfectly fine. The only caveat here (which I am sure you are aware of), is that your REST service should run over SSL, as Basic HTTP authentication is not very secure - username and password are just Base64 encoded.

Secure client token authentication for API

I have a mobile iOS application that I want to authenticate to a RESTful API.
Every user potentially has multiple devices linked to the same account.
So far I came up with the following:
Client-side
Let user login with username/password
Send username/password & unique device id to server
Get authToken from server and set it in the HTTP Authentication header for each API call
On logout, remove authToken
Server-side
API uses SSL
user has many associated devices
devices are represented by unique device id and authToken
each time the user changes password, regenerate all authTokens
if a device is removed, delete authToken for that device
Would that be a secure approach to access the API and manually add/revoke devices?
Yes, this is a fairly standard approach. Google has a document that describes this approach (a majority of the document is geared toward getting the token from the server to the client so that may not be as useful to you). And some more detailed description of bearer token authentication.
You should see if the application framework you're writing the server in already supports an authentication mechanism like OAuth, so you won't have to write your own.