Handling authentication in a multi-tier architecture - android

I'm writing an API, that will be used by a webapplication and native iPhone and Android apps.
The users will create accounts, login, logout etc, either through the webapplication or native apps. But all the business logic is in the API. Thus, the webapplication and the native apps are mostly thin layers containing only UI to integrate with the api.
Question:
What are some general ways/technologies used to authenticate users against the API, when you have this outer layer of either a webapplication or a native app.
Related questions
Authenticating users in iPhone app

Disclosure: I work at Auth0.
Tokens! Tokens! Tokens!
The most widespread approach to authenticate users in a Web API is through the use of token-based authentication. The procedure can be reduced to these steps:
The client application includes a token in the request (Authorization header).
The Web API validates the token and, if valid, processes the request in accordance to the information associated with the token.
This type of token is usually referred as a bearer token, because the only thing that an application has to to get access to an API protected resource is provide the token. The use of HTTPS with this type of authentication is vital in order to ensure that the token cannot be easily captured by an attacker when traveling from client to server.
The token can be classified further either as:
by-value token - associated information is contained in the token itself
by-reference token - associated information is kept on server-side storage that is then found using the token value as the key
A popular format used for by-value token is the JWT format (Get Started with JSON Web Tokens) given it's encoded in a Web friendly way and also has a fairly concise representation in order to reduce overhead on the wire.
Choosing between by-value or by-reference token is a matter of considering the pros and cons of each approach and review any specific requirements you may have. If you go with JWT, check jwt.io for reference on libraries supporting this format across a wide range of technologies.
How does my application get the tokens in the first place?
Setting up your API to authenticate users with tokens can be seen as the easiest part, although the need to think about all the usual security precautions still applies.
The biggest issue with token-based authentication system, is putting in place a system that can issue tokens to your different client applications that may use different technologies or be in completely different platforms.
The answer to this, as mentioned on another answers, is to rely on OAuth 2.0 and the OpenID Connect protocols and do one of the following:
Implement an identity provider/authorization server system compliant with the mentioned protocols
   ⤷ time consuming and complex, but you're following standards so you're less likely to mess up and you'll also gain interoperability
Delegate the authentication to a third-party authentication provider like Auth0
   ⤷ easy to get started, depending on amount of usage (the free plan on Auth0 goes up to 7000 users) it will cost you money instead of time

You should check out
OpenID
OAuth
and have an Identity Server set up.
Depends on what technology you are using, IdentityServer is widely available
one is IdentityServer4 on a .net platform
Please do not hesitate to ask more! :D

I agree with #Fabian Bettag and #WickStargazer.
You can use OAuth 2.0 which works very well with web-app, mobile client and java-script client. Also you can use OpenID Connect 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 inter-operable and REST-like manner.
OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol.
Note :- You can also implement SOAP for login,registration and logout(Security sensitive APIs) to add more security to your app.
Hope this will help and let me know for any help. Happy coding!!!

Related

Unauthorized API Calls - Secure and allow only registered Frontend app

I have backend api in Laravel and using Laravel Passport(OAuth2). I see OAuth2 is super cool and secures my auth request (with api middleware in laravel) and allow access only to authorized users.
But i can access the backend api for unauthorised usage for example
Routes: (/register) or (/login) without any api key. Most attackers will see this api call in network tab and can send DDOS attack. Since Laravel Passport has rate-limiting inbuilt, still i don't want people to access my backend api, unless i allow it manually.
What i want:
I have two frontend apps.
Android Native Mobile app.
Nuxt SPA frontend app
My API should work only from these frontends. No other postman or browser request should pass and probably should display unsupported platforms json msg.
OAUTH TOKENS ARE THEY REALLY ENOUGH TO PROTECT YOUR BACKEND?
I see OAuth2 is super cool and secures my auth request (with api middleware in laravel) and allow access only to authorized users.
It allows access to any request that presents a valid OAuth token, not only for authorized users. This is an usual misconception among developers, because the OAuth token only represents who is in the request, not what is making the request, and I discussed this in more detail in this article, where you can read:
The what is the thing making the request to the API server. Is it really a genuine instance of your mobile app, or is it a bot, an automated script or an attacker manually poking around your API server with a tool like Postman?
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.
The article is in the context of a mobile app, but the concept is the same for both the mobile app and web app in terms of knowing the difference between who and what is making the request to the backend server.
UNAUTHORIZED USAGE OF THE BACKEND
But i can access the backend api for unauthorised usage for example
I hope that by now you have realized that is not only your routes to /register and /login that are at danger of being abused, because at the moment you only know who is making the request, not what is making it.
Routes: (/register) or (/login) without any api key.
Even if you have an API key on this routes, it would not prevent it from being abused for credential stuffing attacks.
Why you may ask?
Well in a web app all it's needed to extract an API key is to hit F12 to open the developer tools tab and search for it, or view the page source.
You may now think, oh but in my mobile app it would not be possible, because it's a binary, and I even use obfuscation. Despite being a little more difficult is not hard, because a lot of open source tools exist to help with the task.
Reverse Engineering
You can use a tool like MobSF to reverse engineer any mobile app binary, and extract the API key or any secret from it. I wrote the article How to Extract an API Key from a Mobile App by Static Binary Analysis that you can follow for a practical example of doing it so, and also shows you several techniques to hide the API key in a mobile app with the Android Hide Secrets repo from Github.
MobSF:
Mobile Security Framework (MobSF) is an automated, all-in-one mobile application (Android/iOS/Windows) pen-testing, malware analysis and security assessment framework capable of performing static and dynamic analysis.
If you cannot extract the API key via static analysis, then you can resort to dynamic analysis with open source tools to, like 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.
Frida will allow at runtime to steal your OAuth tokens and sent them to the attackers control servers, from where they can then reuse it to launch automated attacks to your backend, that will trust they are legit, because the who in the request is valid.
Another approach to steal an API key or even OAuth tokens is to perform a Man in the Middle(MitM) Attack wit another open source tools, like mitmproxy:
An interactive TLS-capable intercepting HTTP proxy for penetration testers and software developers.
So when attacker uses mitmproxy to intercept the request being made to the backend, he will see something like this:
Image sourced from article: Steal that API key with a Man in the Middle Attack
Did you noticed that the url is in https and contains an API Key?
So until now you though that https was enough to secure the communication between clients and server?
WHAT YOU WANT
What i want:
I have two frontend apps.
Android Native Mobile app.
Nuxt SPA frontend app
My API should work only from these frontends. No other postman or browser request should pass and probably should display unsupported platforms json msg.
The web apps
Due to the nature of how the web was built it's not possible for the backend to identify, with an high degree of confidence, what is making the request for any type of web app, be it a SPA or the traditional ones.
The best you can do is to apply User Behavior Analytics(UBA) in a best effort basis to tell appart who and what is accessing your backend:
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.[1] Instead of tracking devices or security events, UBA tracks a system's users.
A good example of using a UBA solution is to use
Google Recaptcha V3:
reCAPTCHA is a free service that protects your site from spam and abuse. It uses advanced risk analysis techniques to tell humans and bots apart.
This is prone to false positives, therefore you need to be careful when deciding to accept or not the request based on the score returned by reCPATCHA V3 for each request:
reCAPTCHA v3 returns a score for each request without user friction. The score is based on interactions with your site and enables you to take an appropriate action for your site.
For mobile apps
By now you are already aware that the OAuth token to identify your user is not that "safe" as you had though initially, because it only identifies the who in the request, not what is doing it, and as you also saw by the plethora of tools available to reverse engineer mobile apps, the OAuth token is always at danger of being stolen and abused by unauthorized clients.
The solution that can let your backend to be sure that the request is indeed from the same exact mobile app that was uploaded to the Google Play store is a Mobile App Attestation solution, and this is a concept that introduces a new approach of dealing with security for your mobile app and backend in an unified manner.
The usual solutions focus to much on the mobile app itself, but in first place the data you want to protect is in your backend server, and it's here that you want to have a mechanism to know that what is making the request is really the thing you expect, your genuine mobile app.
The Mobile App Attestation concept is described in this section of another article I wrote, from where I will quote the following text:
The role of a Mobile App Attestation service is to authenticate what is sending the requests, thus only responding to requests coming from genuine mobile app instances and rejecting all other requests from unauthorized sources.
In order to know what is sending the requests to the API server, a Mobile App Attestation service, at run-time, will identify with high confidence that your mobile app is present, has not been tampered/repackaged, is not running in a rooted device, has not been hooked into by an instrumentation framework (Frida, xPosed, Cydia, etc.) and is not the object of a Man in the Middle Attack (MitM). This is achieved by running an SDK in the background that will communicate with a service running in the cloud to attest the integrity of the mobile app and device it is running on.
On a 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 know. In the case that attestation fails the JWT token is signed with an incorrect secret. Since the secret used by the Mobile App Attestation service is not known by the mobile app, it is not possible to reverse engineer it at run-time even when the app has been tampered with, is running in a rooted device or communicating over a connection that is the target of a MitM attack.
The mobile app must send the JWT token in the header of every API request. This allows the API server to only serve requests when it can verify that the JWT token was signed with the shared secret and that it has not expired. All other requests will be refused. In other words a valid JWT token tells the API server that what is making the request is the genuine mobile app uploaded to the Google or Apple store, while an invalid or missing JWT token means that what is making the request is not authorized to do so, because it may be a bot, a repackaged app or an attacker making a MitM attack.
Taking this approach will let your backend server to know with a very high degree of confidence what is making the request, the same exact mobile app you uploaded to the Google Play, provided the JWT token has a valid signature and expire time, and discard all other requests as untrustworthy ones.
SUMMARY
For web apps your protection is more limited, and in my opinion User Behavior analytics in the backend may be the best option for you.
For mobile apps a huge plethora of solutions exist, but they focus on the mobile app itself, leaving the backend vulnerable to trust in requests that mimic the mobile app, but with a Mobile App Attestation solution the backend is able to tell apart requests from genuine mobile and from fake ones.
GOING THE EXTRA MILE
Now I would like to recommend you the excellent work of the OWASP foundation:
The Web Security Testing Guide:
The OWASP Web Security Testing Guide includes a "best practice" penetration testing framework which users can implement in their own organizations and a "low level" penetration testing guide that describes techniques for testing most common web application and web service security issues.
The Mobile Security Testing Guide:
The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.

Correct way to implement anonymous authentication for an application?

I'm looking for your input in authentication to a rest api related question.
Now Imagine the following scenario:
I have an android app that wants to use resources provided by an public API called MAIN_API (which i have no control over) that has a universal API key. The API key grants access to risky actions such as deleting records.
Now i want to allow the users of the app to have a very limited access to the API resources, but i want them to be able to use the application anonymously ( no credentials of their own).
I figured that the best way to approach this is to have another server that would contain the API-key and would provide the means for the limited access for the MAIN_API (for example PROXY_API would only call simple query endpoints). The actual mobile app would call this API. Call it PROXY_API for the purpose of explanation
Do you think this approach is enough to stop malicious usage of the MAIN_API? Do you think it would be beneficial to generate some sort of application credentials getting an access token from the PROXY_API?
To provide basic authentication to a web service is quite simple and will depend on the technology stack you are using on the server.
I'd recommend that if you need to both grant users and client applications access to resources to use an authorization mechanism such as OAuth. There are Opensource OAuth server implementations available. Though the OAuth server is a standalone component, securing your resource server to check authorization against the actual OAuth server may depend on your technology stack.
If you are not very knowledgeable about security, and want to control access to your API/Webapp using OAuth, I'd recommend you a service like Stormpath, Auth0 or 3Scale. They first two offer free accounts and can help you kick start your product.

User authentication methods for REST api project

My web server has a REST API. I need to add user authentication to my app, and my thought process behind it is this:
Get the user's username and password from the app form
Encrypt the password and Base64 encode both the username and password
Send the data to the REST API over HTTPS
Web server verifies credentials, returns errors or success
Is this secure? I see a lot of mentions of OAuth2. What is it? What does it do better than my process?
The fact that you used the word "encrypt" for the users password instead of "hash" demonstrates you have fairly limited knowledge about this. This will almost certainly result in you messing up your authentication procedures somewhere along the line and put your users private information at risk.
A really important point about OAuth2 is that it can be used with many existing third party providers (Google, Facebook, Twitter, etc) with minimal effort from you.
You don't need to do anything to store credentials or even authenticate users. The third party takes cares of all of this and simply provides the client with a token (long random string) which is then passed to your server. Your server then talks to the third-party server to make sure the token is valid (and gain any info you need, like the users' name, email address or other information).
You really should consider using it if you can. The big companies put a lot of effort into securing their authentication methods and you gain all of that by making use of it.
A final nice point is that users don't need to create and remember credentials for (yet) another account.
Google has some docs to get you started and includes an OAuth playground to test how it works in practise.
A very basic explanation of OAuth2 is that the user will log into your system, with it encrypting both username and password before sending it, then if it gets authenticated, it will send back a token to the user.
Thereafter, whenever the user tries to contact the web server, it will send this token along with each API call. This is how it makes sure that non-authenticated people can't access your web server.
So basically your current method includes parts of the OAuth2 standard, but not the most important part (The token).
In your situation, how would you stop non-authenticated people from accessing your web server? If the project is small, then the risk of this is not that large.. But for larger companies, this is a real threat that needs to be dealt with.
You should really try to understand the difference between encryption and hashing before providing an authentication portal for your users. There are many different hashing algorithms you can use. I've personally used BCrypt in the past and I have a related SO Question about it as well. You can find implementations of pretty much all the popular algorithms in pretty much all the major high level languages these days.
Obviously if you don't want to do all that you can use an OAuth provider, who will take care of all the hard bits like storing the passwords securely, protecting the database and all the other security aspects for you. There are many reliable OAuth providers, Google, Facebook, Yahoo, etc. etc.
One thing to bear in mind would be the environment in which your app is hosted. OAuth does depend on having a connection available to the OAuth provider's servers every time a user wants to access your app. So, if you are behind a corporate firewall or similar which may block access to websites like Facebook, this might be a big problem.
I personally prefer token based authentication for my API projects. If you're not familiar with token based authentication you can read this SO Question and this link.
The general concept behind a
token-based authentication system is
simple. Allow users to enter their
username and password in order to
obtain a token which allows them to
fetch a specific resource - without
using their username and password.
Once their token has been obtained,
the user can offer the token - which
offers access to a specific resource
for a time period - to the remote
site.

secure a REST API for use by Android clients

We're developing a JSON REST API in Rails to be consumed by an Android application, which we are also developing. Is there any way to secure the API such that it can only be used by our specific Android application?
The API is read-only, and does not involve any kind of user-related or otherwise sensitive information. But to the extent that is reasonable we'd like to prevent abuse and restrict its use to only our app.
I could easily add an authentication token to the API and distribute it with the app, but:
We'd probably have to move the API over to SSL, if we use BASIC auth.
It's probably trivial for a determined person to open up the Android APK binary and uncover the auth token anyway.
The situation seems analogous to a café posting their WiFi password on the shop counter- you have to give the secret out to everyone who wants to use your service, so it almost seems pointless to have it in the first place.
What's the most reasonable approach to take?
Wanting to secure a probably public undocumented API so it can only be accessed by one application, means you want to stop people from using your API who are determinate of using your API.
Meaning people who would try everything possible to use your API.
If this is not the case adding a Auth token won't be trivial but at least a big stepping stone for people who stumble upon your API. And not a very bad idea to implement this.
Because this authentication isn't user based but application based and you don't want authentication to rely on user input. The request must be purely done so by the application.
Meaning you will have to do so anyway(adding hardcoded token). Only you make it very very difficult for a determined person to uncover the access and request tokens and the methods.
It depends on the situation, but I would go for the SSL and hardcoded token.
Some extra security:
Release an access token to the application which only need to send a
request token periodically. Meaning less chance people intercept the
hardcoded request token, but a session based access token which
expires. Maybe just do this once for every application install.
Encode this request token before sending it through the air. Meaning
people have to decompile your app.
Obfuscate code (make it more difficult to decompile).

How should I properly impliment HTTP(S) auth (REMOTE_AUTH) in django?

I am in the planning phase a new project. I want to be able to control multiple relays from my android powered phone over the internet. I need to use an HTTP based server as a middleman between the phone and the relays. Django is my preferred platform because Python is my strongest skill set. This would not be a "web app" (with the exception of the admin interface for managing the user and their access to the relays). Rather, the server would simply provide an API in the form of HTTPS requests and JSON encoding. Though, I should note that I have never done any web development in my life, so I don't know best practices (yet). The authentication method should meet the following criteria:
Works over HTTPS (self-signed SSL)
Provides multi-factor authentication (in the form of something you have and something you know)
Be reasonably secure (Would be very difficult to fool, guess at. or otherwise bypass)
Is simple in implementation for the server operator and end user on the mobile client
Is lightweight in in terms of both CPU cycles and bandwidth
I plan to use the following scheme to solve this:
An administrator logs into the web interface, creates a user, and sets up his/her permissions (including a username and a password chosen by the user).
The user starts the client, selects add server, and enters the server URL and his/her credentials.
The client attempts to authenticate the the user via HTTP auth
(over SSL). If the authentication was successful, the server will generate an API key in the form of a UUID and sends it to the client. The client will save this key and use it in all API calls over HTTPS. HTTP auth is only used for the initial authentication process prior to reviving a key, as a session scheme would not be nessessary for this application. Right? The client will only work if the phone is configured to automatically lock with a PIN or pattern after a short timeout. The server will only allow one key to be generated per user, unless an administrator resets the key. Hence, simple, mobile, multifactor authentication.
Is this sound from a security standpoint? Also, can anyone point me to an example of how to use the HTTP auth that is built into Django? From a Google search, I can find a lot of snipits witch hack the feature together. But, none of them implement HTTP auth in the wayit was added to Django in 1.1. The official documentation for REMOTE_AUTH can be found here, but I am having difficulty understanding the documentation as I am very new to Django.
I'm not entirely sure of how basic auth would work on Django, but I can take a shot.
The basic auth article on wikipedia covers a pretty standard usecase for logging in. For Android I've personally skipped the first part (401) and just pass my credentials in right away.
With your auth request you will have to just grab the user credentials from the request headers (WWW-Authenticate) and then do all the necessary work for that. With the credentials you can then just use the authentication framework provided in Django to verify that the user then generate their UUID (I guess).
As for basic auth on Android it's a little bit tricky at first and may leave you pulling your hair. I've found this article on Basic HTTP auth for android which helps explain how to do it.
As for the security part of it, I'm not too sure. It's pretty simple, which I'd say is a good thing :)

Categories

Resources