REST API authentication for mobile application iOS and Android - rest

I want to securely access the REST API(.net) through a mobile application(react-native). I had the following solutions but each one has its drawback. Can someone suggest me the solution to the problem?
1.
REST API: secure rest API with username & password.
Mobile App: send username and password with every rest API call.
Drawback:
On reverse engineering username and password is obtained which is stored in the mobile application. The code was obfuscated and password was stored at places but hackers were successful to obtain password after doing certain efforts.
2.
REST API: auth 2 implemented
Mobile App: call Rest API to obtain Token for future use but the first time required to pass auth credentials to obtain token. Same problem username & password can be obtained by reverse engineering.
How we can move app secrets out of the app and can access REST API securely from the mobile application?

You should look to implement the Authorisation Code Grant with PKCE.
Here is an example project doing something similar.

Three things for you:
1) I would definitely recommend OAuth2 over repeatedly sending username-password. It's well understood and there are both open source and free commercial implementations available. On mobile, PKCE is very important to prevent Auth Code interception attacks.
2) Using HTTPS for your REST API calls is a given, but I would encourage you to pin those connections as well. An attacker can easily compromise a mobile device and man-in-the-middle your API calls otherwise. Pinning is tricky for React Native; take a look at the react-native-cert-pinner npm package and/or read Strengthen TLS in React Native through Certificate Pinning (Android) or iOS.
3) OAuth2 with PKCE won't stop an impersonation attack, and especially if you are creating users with trust-on-first-use, you will be even more vulnerable to bot attacks. You should do more than just simple API keys. I would recommend some well-obfuscated signing of API calls or, even better, some form of app attestation. For React Native, see First experiences with React Native: bridging an Android native module for app authentication or similarly for iOS.

Related

Protocol for password-less authentication in clis

I have a cli (which use a rest api) which needs authentication for use.
As of right now, it supports a token auth. This token is generated at the server on a request with username and password and given as the response.This is not ideal (due to man in the middle attacks) and I am looking for a better protocol to use to generate the tokens.
Users will use such a protocol from a cli, and may or may not have access to a browser on the same device (Though a protocol that requires opening a website is not a problem)
The OAuth device flow seems to be a very simple to use flow, but it is meant
for authorization and not authentication. I also do want to support OAuth as that will require a lot of work, and frankly not what I need.
What is the standard or recommended protocol to use in such a situation?
MITM should not be an issue if your server and app are properly securing the connection. There is nothing really wrong in using a username+password to connect to your backend services. After all, when you're logging into the site you're sending an HTTP request with your username and password to a backend the same way your cli app would do it.
But OAuth indeed can a better fit for cli app:
it's easier to revoke the stolen OAuth token than to force user to change a password,
an app doesn't have to deal with user credentials (although OAuth credentials flow is also exists),
it gives you flexibility when creating new tokens. For example, you may want to issue short lived tokens only to force the user to re-login each time the app is used or you may want to use long-lived refresh tokens.
As you already mentioned, OAuth doesn't handle authentication but you can use your current login flow to verify user credentials and issue an OAuth token (how exactly do that is a separate topic).
I don't think there is a special protocol targeting authentication in cli apps. In any case the app would need to send some secret to a backend. One of the possible solutions is to use OTP (e.g. SMS or email code). In this case you send the code the same way as you would send a password but it is better protected against MITM attacks because a code cannot be used more than once.

Mobile app/API security: will a hardcoded access key suffice?

I'm building a mobile app which allows users to find stores and discounts near their location. The mobile app gets that information from the server via a REST API, and I obviously want to protect that API.
Would it be enough to hardcode an access key (128 bit) into the mobile app, and send it on every request (enforcing https), and then check if it matches the server key? I am aware of JWT, but I believe using it or other token-based approach will give me more flexibility but not necessarily more security.
As far as I can see the only problem with this approach is that I become vulnerable to a malicious developer on our team. Would there be a way to solve this?
First, as discussed many times here, what you want to achieve is not technically possible in a way that could be called secure. You can't authenticate the client, you can only authenticate people. The reason is that anything you put into a client will be fully available to people using it, so they can reproduce any request it makes.
Anything below is just a thought experiment.
Your approach of adding a static key, and sending it with every request is a very naive attempt. As an attacker, it would be enough for me to inspect one single request created by your app and then I would have the key to make any other request.
A very slightly better approach would be to store a key in your app and sign requests with it (instead of sending the actual key), like for example to create a hmac of the request with the key and add that as an additional request header. That's better, because I would have to disassemble the app to get the key - more work which could deter me, but very much possible.
As a next step, that secret key could be generated upon the first use of your app, and there we are getting close to as good as this could get. Your user installs the app, you generate a key, store it in the appropriate keystore of your platform, and register it with the user. From then on, on your backend you require every request to be signed (eg. the hmac method above) with the key associated with your user. The obvious problem is how you would assign keys - and such a key would still authenticate a user, and not his device or client, but at least from a proper keystore on a mobile platform, it would not be straightforward to get the key without rooting/jailbraking.But nothing would keep an attacker from installing the app on a rooted device or an emulator.
So the bottomline is, you can't prevent people from accessing your api with a different client. However, in the vast majority of cases they wouldn't want to anyway. If you really want to protect it, it should not be public, and a mobile app is not an appropriate platform.
YOUR PROBLEM
Would it be enough to hardcode an access key (128 bit) into the mobile app, and send it on every request (enforcing https), and then check if it matches the server key?
Well no, because every secret you hide in a mobile app, is not anymore a secret, because will be accessible to everyone that wants to spend some time to reverse engineer your mobile app or to perform a MitM attack against it in a device he controls.
On the article How to Extract an API key from a Mobile App by Static Binary Analysis I show how easy is to extract a secret from the binary, but I also show a good approach to hide it, that makes it hard to reverse engineer:
It's time to look for a more advanced technique to hide the API key in a way that will be very hard to reverse engineer from the APK, and for this we will make use of native C++ code to store the API key, by leveraging the JNI interface which uses NDK under the hood.
While the secret may be hard to reverse engineer it will be easy to extract with a MitM attack, and that is what I talk about in the article Steal that API key with a MitM Attack:
So, in this article you will learn how to setup and run a MitM attack to intercept https traffic in a mobile device under your control, so that you can steal the API key. Finally, you will see at a high level how MitM attacks can be mitigated.
If you read the article you will learn how an attacker will be able to extract any secret you transmit over https to your API server, therefore a malicious developer in your team will not be your only concern.
You can go and learn how to implement certificate pinning to protect your https connection to the API server, and I also have wrote an article on it, entitled Securing Https with Certificate Pinning on Android:
In this article you have learned that certificate pinning is the act of associating a domain name with their expected X.509 certificate, and that this is necessary to protect trust based assumptions in the certificate chain. Mistakenly issued or compromised certificates are a threat, and it is also necessary to protect the mobile app against their use in hostile environments like public wifis, or against DNS Hijacking attacks.
Finally you learned how to prevent MitM attacks with the implementation of certificate pinning in an Android app that makes use of a network security config file for modern Android devices, and later by using TrustKit package which supports certificate pinning for both modern and old devices.
Sorry but I need to inform you that certificate pinning can be bypassed in a device the attacker controls, and I show how it can be done in the article entitled Bypass Certificate Pinning:
In this article you will learn how to repackage a mobile app in order to make it trust custom ssl certificates. This will allow us to bypass certificate pinning.
Despite certificate pinning can be bypassed it is important to always use it to secure the connection between your mobile app and API server.
So and now what, am I doomed to fail in defending my API server... Hope still exists, keep reading!
DEFENDING THE API SERVER
The mobile app gets that information from the server via a REST API, and I obviously want to protect that API.
Protecting an API server for a mobile app is possible, and it can be done by using the Mobile App Attestation concept.
Before I go in detail to explain the Mobile App Attestation concept is important to we first clarify an usual misconception among developers, the difference between the WHO and the WHAT is accessing your API server.
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.
Mobile App Attestation
The role of a Mobile App Attestation solution is to guarantee at run-time that your mobile app was not tampered with, is not running in a rooted device, not being instrumented by a framework like xPosed or Frida, not being MitM attacked, and this is achieved by running an SDK in the background. The service running in the cloud will challenge the app, and based on the responses it will attest the integrity of the mobile app and device is running on, thus the SDK will never be responsible for any decisions.
Frida
Inject your own scripts into black box processes. Hook any function, spy on crypto APIs or trace private application code, no source code needed. Edit, hit save, and instantly see the results. All without compilation steps or program restarts.
xPosed
Xposed is a framework for modules that can change the behavior of the system and apps without touching any APKs. That's great because it means that modules can work for different versions and even ROMs without any changes (as long as the original code was not changed too much). It's also easy to undo.
MiTM Proxy
An interactive TLS-capable intercepting HTTP proxy for penetration testers and software developers.
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
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.
DO YOU WANT TO GO THE EXTRA MILE?
OWASP Mobile Security Project - Top 10 risks
The OWASP Mobile Security Project is a centralized resource intended to give developers and security teams the resources they need to build and maintain secure mobile applications. Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.

How to protect signup, login REST APIs from being called from anonymous source without using API Gateways?

I'm building a mobile application interacting with backend providing REST APIs. Most of the APIs are protected by access_token provided to a success login.
However I'm curious that WHO will protect the signup, login APIs from anonymous callers, as those APIs don't require access_token (assuming that the system handle DDOS well)? Using API Gateway like Kong with its OAuth to protect all APIs seems to be proper solution but somehow a bit overkill for small/medium/no-micro-service projects.
Some of my simple ideas is to use a set of predefined username-password pairs for Basic auth or more complicated one like Digest auth or an OAuth layer putted before API routes. Mobile app keep those secrets then use them to make signup, login API requests.
Do we any other solutions here?
Mobile app keep those secrets then use them to make signup, login API requests.
Please do not put any secret at all in your Mobile App once they can be easily reverse engineered with frameworks like Xposed.
Mobile Apps can be made more secure and difficult to reverse engineer by using some techniques to secure the secrets both in the Mobile APP and in the API server, like:
Certificate Pinning to protect the communication channel between the Mobile App and the API.
HMAC signed/encrypted messages.
Signed JWT Tokens with encrypted content.
OAUTH2 as a more secure alternative for authenticate your users.
Advanced code obfuscation techniques in the Mobile App code.
You can read more about how some of this techniques can be used and bypassed on this article.
However I'm curious that WHO will protect the signup, login APIs from anonymous callers
If you have read the article I linked above, about Mobile API techniques, you are aware that you need to protect all API endpoints, even the ones behind the authentication, otherwise you will be subject to API abuse of your endpoints by automated scripts, bots, crawlers and all kind of attackers that may profit from your service or data.
For hardening the security between your Mobile App and the API server you should use a Mobile App Attestation service, that will guarantee at run-time that your App was not tampered or is not running in a rooted device by using an SDK integrated in you App and an attestation service running in the cloud, that will emit a signed JWT token that then the API server can validate to distinguish a valid request from a fake one.
JWT Token
Token Based Authentication
JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.
Certificate Pinning
Pinning is the process of associating a host with their expected X509 certificate or public key. Once a certificate or public key is known or seen for a host, the certificate or public key is associated or 'pinned' to the host. If more than one certificate or public key is acceptable, then the program holds a pinset (taking from Jon Larimer and Kenny Root Google I/O talk). In this case, the advertised identity must match one of the elements in the pinset.
OAUTH2
The OAuth 2.0 authorization framework enables a third-party
application to obtain limited access to an HTTP service, either on
behalf of a resource owner by orchestrating an approval interaction
between the resource owner and the HTTP service, or by allowing the
third-party application to obtain access on its own behalf. This
specification replaces and obsoletes the OAuth 1.0 protocol described
in RFC 5849.

Authentication with Akka-Http

We're developing an iOS app, where the user needs to authenticate using email+password (or mobile number). Our backend is made of a couple of microservices using Akka-Http. It needs to be fast, scalable, concurrent, and the authentication+authorization should work across our multiple services.
I'm trying to figure out which authentication method to use.
Akka-HTTP currently offers Basic Auth and a partial implementation of OAuth2.
So at first we were considering Basic authentication (too simple and not enough functionality), Oauth1 (too complex), so we moved towards OAuth-2.0 because it is sort of a standard.
Then we considered AWS Cognito because it combines Oauth-2.0 and OpenID Connect which gives the authentication mechanism that OAuth2 lacks.
http://www.thread-safe.com/2012/01/problem-with-oauth-for-authentication.html
Then we realised that OAuth2 is just for authentication using a third party - when in fact we don't need a third party authentication provider - maybe we need to do it ourselves, and using Cognito is an overkill that would create extra api calls outside our microservices...
So I read a little bit about creating our own custom auth provider, using WSSE specs:
http://symfony.com/doc/current/cookbook/security/custom_authentication_provider.html
And I also found this example using Spray, but I'm sure it's not that different from Akka-Http:
http://danielasfregola.com/2015/06/29/how-to-create-a-spray-custom-authenticator/
It looks too simplified and doesn't have token expiration...
So my question is, am I missing something? What method should I chose and where can I find examples for it?
I feel like I'm going in circles, we're gonna have to write our own custom authentication provider from scratch, which kinda doesn't make sense. After all almost everybody needs authentication and it should be a standard.
I've recently been using SoftwareMill's akka-http-session library and found it simple and easy to integrate. It has support for case class based sessions, JWTs, refresh tokens with pluggable storage, using headers and CSRF tokens as well as some nice simple directives for use in routes.
My solution for user registration has been to use Keycloak, an open source server which can handle user registration and do OIDC, OAuth2 style login. It reduces the amount of code I have to write, and the code is more secure than if it rolled it myself.
I then write my application as Scala backend that's purely a JSON API and a React/Javascript rich frontend in front of that API. In this configuration the authentication is handled completely on the front-end (and can be done in your iOS client). The front-end app redirects the user to Keycloak and when the user comes back they have a signed "JWT" token you can keep in a cookie.
That JWT token is attached to all API calls made the JSON backend as an Authorization Bearer token HTTP header. The token itself contains the users email address and is cryptographically signed by the Keycloak server.
The backend gets the JWT token in the HTTP header, extracts the email address and verifies the token is cryptographically signed by the keycloak server.
It's performing a certificate check on the keycloak server and can cache it's certificate. So it doesn't need to have roundtrips like OAuth, or any upstream calls to make.
This gives us simple, low-chance-of-failure, high speed authorisation in our JSON backend API and means we aren't putting secrets in the iOS client, or rolling too much of our own code.

Accessing REST APIs secured using OAUTH

I have a set of REST APIs that are secured by oauth 2. I need to access them from an Android app and a webapp.
Accessing the APIs from android app seems pretty straight forward for me to implement. What I am unable to understand here is - what is the correct and secure way to access the same APIs from a webapp?
I am thinking, I shouldn't be making any direct calls to the APIs from the browser, using some JS library, for it seems to me that it would be pretty insecure. Instead, I should keep it all traditional, by submitting requests to the web server and then letting it make the REST API call. This would be similar to the method of making REST calls from Android.
Am I correct in my thinking/approach?
Accessing your API should be the same no matter where the request is coming from. You just use an Authorization header with bearer scheme and stick the JWT token in there.
The way you get the JWT token is different though, as I explain in this answer. It all depends on how much you trust the client application.
If your client is a web application that queries your API from the server side, you can use the code authorization grant and get an access and refresh token for your API.
If you want to access your API from a JavaScript application, you have no way to hide app-keys or refresh tokens, so you should use the implicit grant.
If you know how to store secrets securely on your Android client, you could use the resource owner password grant.
The code authorization grant is definitively the most secure as it's much harder to compromise a server application than an application that runs on your machine.