Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Secure API for both mobile and web

I have three applications:

  • REST API
  • Single Page Web App
  • Native Mobile App.

Both the web app and the mobile app uses the API for user authentication and fetching user specific data.

My problem is then how to secure this API against CSRF, XSS and other types of attacks.

As I understand, there are two common authentication strategies that each has pros and cons:

  • Token based authentication
  • Session/cookie based authentication (secured and httponly)

Session/cookie based authentication

Cookies are vulnerable to CSRF attacks, so to protect against that i would need to implement CSRF tokens, or a similar protection strategy. For a secure CSRF token implementation I should also setup proper CORS policy, so foreign sites can't get a CSRF token from the API. This is also good and well for the web app, however not possible for the mobile app, as mobile apps doesn't support CORS (it has now domain or origin header).

Token based authentication

The alternative is token based authentication, which works well for mobile apps, and removes the need for CSRF tokens as they themselves validates the authenticity of the request. However there are no secure way to store tokens in a Single Page Web App (locale/web storage is not secure, and if I use cookies, we are basically back to our first problems).

Problem

So my problem is, how should i implement secure authentication for both apps?

My current idea would be to implement both strategies but only allow token auth when origin is not present, and only allow session/cookie auth when origin header is present and allowed by the CORS policy.

But I'm in no way an expert on the subject, and might easily have misunderstood something. Any suggestions or further explanations would be very welcome :)!

like image 327
railsdev Avatar asked Jan 11 '19 11:01

railsdev


People also ask

Is an API same for web and mobile?

What Is an API For Mobile Apps? An API — application program interface — is used in mobile apps just like it is in web apps. It allows developers to access another application or platform. APIs are the foundational element of a mobile app strategy.

How can I protect my mobile API?

API calls are typically protected by a simple API key and user credentials, most often in the form of an access token. These tokens are like cash, so if you can get one, by registering for your own account or stealing someone else's, you can spend it however you wish.

Which API is more secure?

In general, SOAP APIs are praised for having more comprehensive security measures, but they also need more management. For these reasons, SOAP APIs are recommended for organizations handling sensitive data.

How secure are APIs?

It’s the age of the digital economy explosion, and massive data loads are being piped through APIs. Business, gaming, education, weather, science, arts . . . you name it; everything works on APIs. For a world so fundamentally reliant on APIs, there’s surprisingly little focus on security.

What are the best tools for API security?

There are several tools you can use but be cautioned that at the end of the day, no security strategy is perfect. Having said that, these tools can increase your API security manyfold, so they are recommended. Metasploit is an extremely popular open-source framework for penetration testing of web apps and APIs.

What is the security context for web APIs?

As Web APIs are stateless in nature, the security context cannot depend on server session. Each request made to the API must attach some form of credentials which has to be validated on the server. Note: The techniques discussed here is on authentication and authorization and does not encrypt transmitted messages.

What is the best way to authenticate an API?

Now, almost every API has a form of authentication, but in my opinion, the OAuth2 system works the best. As opposed to other authentication methods, it divides your account into resources and allows only limited access to the auth token bearer.


1 Answers

Authenticity of the request

The alternative is token based authentication, which works well for mobile apps, and removes the need for CSRF tokens as they themselves validates the authenticity of the request.

Auth tokens cannot be trusted to validate the authenticity of a request, because they only identify the user, not that is the genuine mobile app doing the request.

An attacker controlling the device where the mobile app is running can extract the auth token to automate the requests to the API server. Another technique used by attackers is the creation of a fake captive portal for free wifi(airports, train stations and other public spaces), where they trick who signs in to install a custom ssl certificate in their mobile device, so that the attacker can decrypt the https traffic, thus stealing the auth tokens and perform automated requests to the API server in behalf of the user.

Implementing both strategies

My current idea would be to implement both strategies but only allow token auth when origin is not present, and only allow session/cookie auth when origin header is present and allowed by the CORS policy.

This can be easily bypassed and automated by an attacker. So the attacker would only make requests with the stolen token and without using the origin in the headers of the request, thus avoiding the security for web and bypassing the ones for a mobile app.

Suggestions

But I'm in now way an expert on the subject, and might easily have misunderstood something. Any suggestions or further explanations would be very welcome :)!

I will recomend you to read this series of articles about Mobile API Security techniques, that will give you good insights in how to protect an API. In the article we can see how api-keys, HMAC, certificate pinning, OAUTH can be used to secure the API and also how they can be bypassed. While in the scope of a mobile API some of the techniques are valid in the context of a web app.

For the the web:

Use the Strict Transport Policy header to guarantee that your web app is always loaded over https.

Your web app should use CSP(Content Security Policy) with a report service that will let you know in real-time when any of the policies is violated.

If using cookies you should enable httpOnly flag to protect them from being accessed via javascript. Further more you want to enable the secure flag for cookies to be sent only hover a https connection. Also try to scope cookies by the path they belong to, i.e. cookies for a login page should be scoped to the /login path, thus they will not be sent for other pages or assets(images, css, etc.) of the the web app.

Add recAptcha V3 to all pages of your web app. It runs on the background without any user interaction required and provides a score from 0 to 1, where towards 1 we are more confident that is a human making the request.

Quoting Google:

We are excited to introduce reCAPTCHA v3, which 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.

That score will allow to have some degree of confidence in blocking non human traffic. If you need more confidence then you may want to use also User Behaviour Analytics(UBA) solutions, that may use machine learning and artificial intelligence for further analysis of the incoming traffic and detection of abusive traffic. Due to the way the web works, both reCaptcha V3 and UBA are not able to provide bullet proof solutions to authenticate requests as legit ones.

For Mobile Apps:

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.

Possible Solution

So my problem is, how should I implement secure authentication for both apps?

For the web app:

  • OpenID or OAUTH2 for both mobile and web app and maybe using a cookie to store the auth token, scoped by url path, with httpOnly and the secure flag enabled.
  • Further use strict CSP policies along side with CORS, CSFR, Strict Transport Policy and any other I may be missing now.
  • Google reCaptcha V3.

For the mobile app:

  • OpenID or OAUTH2.
  • Mobile App Attestation solution.
  • Certificate Pinning.

The API will only accept a request that contains a header with the reCaptcha V3 token or with a mobile app attestation JWT token. Any other requests should be denied.

In the case of a web app to proceed further with the request the recCaptcha V3 score(0 to 1.0) should give the confidence that the request comes from an human, maybe greater than 0.9? You will need to play with the value and monitor it in order to find the correct balance.

For a request from a mobile app to be able to continue being processed, the API server must verify that the JWT token have a valid signature and is not expired.

While the web requests are verified in a best effort basis the requests coming from a mobile app protected with the Mobile Attestation service have only 2 possible outcomes, valid or invalid.

like image 154
Exadra37 Avatar answered Oct 19 '22 10:10

Exadra37