Restrict API Requests to Only My Own Mobile App

Restrict API requests to only my own mobile app

Any credentials that are stored in the app can be exposed by the user. In the case of Android, they can completely decompile your app and easily retrieve them.

If the connection to the server does not utilize SSL, they can be easily sniffed off the network.

Seriously, anybody who wants the credentials will get them, so don't worry about concealing them. In essence, you have a public API.

There are some pitfalls and it takes extra time to manage a public API.

Many public APIs still track by IP address and implement tarpits to simply slow down requests from any IP address that seems to be abusing the system. This way, legitimate users from the same IP address can still carry on, albeit slower.

You have to be willing to shut off an IP address or IP address range despite the fact that you may be blocking innocent and upstanding users at the same time as the abusers. If your application is free, it may give you more freedom since there is no expected level of service and no contract, but you may want to guard yourself with a legal agreement.

In general, if your service is popular enough that someone wants to attack it, that's usually a good sign, so don't worry about it too much early on, but do stay ahead of it. You don't want the reason for your app's failure to be because users got tired of waiting on a slow server.

Your other option is to have the users register, so you can block by credentials rather than IP address when you spot abuse.

How to restrict others from using your web api except your app users?

Context

How can I prevent others from using my web apis/services and restrict it only to my app?

You mention web here and in the tags for this question, but it's not explicit that you are referring to a web app or a mobile app.

The users of my app do not need to signup or do anything like that, and they can use the app as soon as they install it on their phone.

Form this I am assuming that you app is a mobile app, because of this sentence: they can use the app as soon as they install it on their phone, and assuming that when you refer to my web apis/services you are indeed referring to a REST API and to third party services like Firebase, that you also mention in the question.

The Difference Between WHO and WHAT is Accessing the API Server

How can I prevent others from using my web apis/services and restrict it only to my app?

By others you seem to mean another human being, the who in the request, but you may want to say instead what software/script/bot is trying to use my web apis/services.

Knowing the difference between what is doing a request to your API server vs knowing in behalf of who the request is being made it's crucial for understanding what security posture and defenses you need to apply in your use case.

I wrote a series of articles around API and Mobile security, and in the article Why Does Your Mobile App Need An Api Key? you I go in more detail about the difference between who and what is accessing your API server, but I will extract here the main takes from it:

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.

You can think about the who as the user your API server would be able to Authenticate and Authorize access to the data and think about the what as the software making that request in behalf of the user.

In your use case the who is not relevant, because you don't have user authentication in your mobile app, thus you need to find a way to identify what is doing the request. So you are looking to lock down your API server to your mobile app, and you found yourself a very challenging issue to solve.

Locking Down the API/SERVICES

For the API Server

How can I prevent others from using my web apis/services and restrict it only to my app?

For the API server to have a high degree of confidence that what is doing the request is indeed your genuine mobile app, and not a bot/script or tampered version of your mobile app, the Mobile App Attestation concept can be used/implemented, and I invite you to read my reply to the question How to secure an API REST for mobile app? on the section for A Possible Better Solution to understand this concept.

NOTE: Just in case you indeed have a web app, and not a mobile app, then I recommend you to read instead this other answer I gave to the question How to secure own backend API which serves only my frontend? and read the section Possible Solutions.

For Firebase

To give a more concrete case, lets say I am using Firebase Realtime Database service. How can I prevent others from using this service on my behalf?

I am not an expert in Firebase, thus I will point you to this answer for the question Locking down Firebase DB access to specific apps.

It seems to me that Firebase security is implemented around security rules and user authentication:

A common first step in securing your app is identifying your users. This process is called authentication. You can use Firebase Authentication to have users to sign in to your app.

But you don't identify who is using your mobile app, thus their first steps doesn't apply to your use case, but it seems that they support anonymous user authentication:

You can use Firebase Authentication to create and use temporary anonymous accounts to authenticate with Firebase. These temporary anonymous accounts can be used to allow users who haven't yet signed up to your app to work with data protected by security rules.

So this may be your best chance to go with in terms of locking your mobile app with Firebase.

In a nutshell it looks like Firebase doesn't have any built-in functionality to identify what is doing the request, because their focus seems to be more in who is doing the request, but once I am not an expert on it I advise you to take this statement with caution and do your own research.

When applying security rules you may want to take in account the resolve insecurities page and use the Firebase Simulator to test the different rules.

Do you want to go the Extra Mile?

In any response to a security question I always like to reference the excellent work from the OWASP foundation.

For Mobile Apps

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.

OWASP - Mobile Security Testing Guide:

The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.

For APIS

OWASP API Security Top 10

The OWASP API Security Project seeks to provide value to software developers and security assessors by underscoring the potential risks in insecure APIs, and illustrating how these risks may be mitigated. In order to facilitate this goal, the OWASP API Security Project will create and maintain a Top 10 API Security Risks document, as well as a documentation portal for best practices when creating or assessing APIs.

Restrict API calls. Allow only my mobile app

Considering that you are deploying an application to a client, the actual answer here is 'not possible'. You can make it difficult for someone to fake an 'official id', but because you do not have control over the system that is making the requests, it could be your application or anything else pretending to be your application.

How to secure an API REST for mobile app? (if sniffing requests gives you the key)

Am I wrong?
Is this a stupid question?

No you are not wrong, and it's not a stupid question at all, because it's indeed easy to attack an API server of a mobile app, and you will be surprised to know how many senior developers are not aware how easy it can be done, and I have noticed that more often then not, this is due to their misconception about what vs who is accessing the API server.

The difference between what and who is accessing the API server.

This is discussed in more detail in this article I wrote, where we 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.

So if the quoted text is not enough to clarify you, then please go ahead and read the entire section of the article.

Impersonating the Mobile APP

In those request I've found a lot of auth keys that I can use in other calls from a console, simulating the app with no problems.

If by auth keys you mean the ones provide via user sign-in, with his username and password, then they just identify the who in the request.

For other keys, like api-keys, access-tokens, or any other convention used to name them, they have the purpose of providing to the API server a mechanism to only authorize requests from the genuine mobile app, they are indeed trying to allow the API server to identify what is doing the request, and has you already discovered it's easy to extract them with a proxy:

Although you use SSL, it's "usually easy" to hack mobile apps (I'm thinking in Android right now: decompiling the app, changing manifest to allow custom SSL, compiling again and sniffing through a SSL proxy all the requests).

So, in the end of the day all an attacker needs it's to use a proxy to learn how the API server works, and what is needed to simulate an API call as if it was done from the mobile app itself.

Hardening and Shielding the Mobile App

So, now I've hacked some API's in mobile apps, my question is: is there any way to secure an API in a mobile app?

You can use Mobile Hardening and Shielding solutions, that will try to prevent the mobile app to work in compromised/rooted devices, with modified/tampered apps and/or when some instrumentation framework is being used during runtime, but all of them have the draw-back of performing all that decisions in the mobile app, therefore subject to be manipulated or totally bypassed by the alreay dito instrumentation frameworks, and a good example of one it's 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.

While is better to use an in app solution, than not using anything, it's still not the ideal solution, because the control of deciding what to do is in the client side, not in the server side, thus the attacker can resort to use Frida to introspect the code at runtime and learn how to impersonate the mobile app.

Securing the API Server

The Basic API Security Defenses

Now that you understand the difference between who vs what is accessing your API server and you know that an attacker can learn how to impersonate your genuine mobile app you may want to go an read my article about the basic techniques to secure an API:

In this article we will explore the most common techniques used to protect an API, including how important it is to use HTTPS to protect the communication channel between mobile app and API, how API keys are used to identify the mobile app on each API request, how user agents, captchas and IP addresses are used for bot mitigation, and finally how user authentication is important for the mobile security and api security. We will discuss each of these techniques and discuss how they impact the business risk profile, i.e. how easy they are get around.

This is only a very basic technique that the majority of APIs may already employ, but they can be reinforced with some more advanced techniques.

More Advanced API Security Defenses

You can start to read this series of articles on Mobile API Security Techniques to understand how API keys, HMAC, OAUTH and certificate pinning can be used to enhance the security and at same time learn how they can be abused/defeated.

Afterwards, and depending on your budget and resources you may employ an array of different approaches and techniques to defend your API server, and I will start to enumerate some of the most usual ones.

You can start 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 implementing a Mobile App Attestation solution that attests the integrity of your mobile app and device its running on before any request is made to the API server.

A Possible Better Solution

The current implementations of a mobile app and API server may look like this:

API direct access from a Mobile App

This approach is what leaves the API keys vulnerable to be extracted by attackers via proxy interception(red line), just like you already noticed by using a proxy to intercept them.

A better approach would be something like this:

No API Key in a mobile app

Wait, but I don't see any API key in the mobile app anymore:

Am I missing something ?

Yes, a Mobile App Attestation solution.

To be in a position where you don't need to ship any secrets with your mobile app, then you need to resort to the Mobile App Attestation concept, and from this article section I will quote the relevant parts to explain it's role:

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.

A great benefit of using a Mobile App Attestation service is its proactive and positive authentication model, which does not create false positives, and thus does not block legitimate users while it keeps the bad guys at bay.

The Mobile App Attestation releases your mobile app from having an embedded secret in its code, instead now it only needs to pass to the reverse proxy or backend the JWT token it receives from the mobile app attestation service. Now the reverse proxy or backend can verify the JWT token, and on successful validation they can accept requests with a very high confidence that they are originated from what they expect, a true and genuine instance of the mobile app, with the added benefit of not exposing the API keys to access your API server or any Third Party services.

GOING THE EXTRA MILE

I cannot finish without recommending you the excellent work done by the OWASP foundation.

For Mobile Apps

OWASP - Mobile Security Testing Guide:

The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.

For APIS

OWASP API Security Top 10

The OWASP API Security Project seeks to provide value to software developers and security assessors by underscoring the potential risks in insecure APIs, and illustrating how these risks may be mitigated. In order to facilitate this goal, the OWASP API Security Project will create and maintain a Top 10 API Security Risks document, as well as a documentation portal for best practices when creating or assessing APIs.

How to restrict access to HTTP API for mobile applications?

I'm not sure that your developers would be able to securely do this without having some form of communication with their own host and some form of user account on their system. As you said, if you included a long-lived token in an app, no matter what obfuscation is done it could eventually be discovered by reverse engineering techniques.

There are 2 options that I can see:

1. Short lived token

In this scheme the mobile application contacts the developer's system to receive an short auth token.
During enrollment and periodically thereafter, developers generate a public-private keypair and give you the public key.

Each auth token would need to include an unencrypted "developer key ID" of some sort and an encrypted bit of data including the token's issue data and a salt of pseudo-random data. The developer's host would encrypt the data using a private key in a public-private keypair. This keeps the secret in a controlled and secure space. The encrypted data needs to include the salt in order to prevent known-plaintext attacks on your developers' keys.

The app sends the token to you, you can determine it's legitimacy by:

  1. Use the unencrypted developer key ID to determine which key to use in decrypting the encrypted string.
  2. Has the developer key ID been revoked or expired? (due to key compromise, dev API subscription expiration or abuse, etc). If it was revoked, deny access.
  3. Does the encrypted data in the token decrypt correctly? If not, deny access.
  4. Has the token expired? (based on the encrypted token date) If so, tell the client to get a new token from the dev server. Their software should do this before contacting your API, but you have to check just in case. I'd suggest that tokens be allowed to live for a relatively short time since copying a token between apps is a weakness.
  5. Allow access

You could also use symmetric encryption instead of public-private key encryption, but then you and the dev both know the secret. It'd be more secure if only the dev knows it.

2. Pass API calls through dev host

It'd be possible for mobile applications to talk to their developer's host instead of your host for calls to the API. When the dev host receives one of the calls, it simply passes the call through to your API and adds their secret token.



Related Topics



Leave a reply



Submit