How do I allow only certain applications to access my API?

Asked

Viewed 1,395 times

10

I am developing an API using Express, which should be used only by an application in the browser, built using React and an application, made using React Native.

The question is: how can I restrict the use of this API so that only these two applications can access it?

I had thought to use CORS, but taking into account that this measure affects only browsers, will not be so useful.


As I mentioned in a comment below, I need to make only my front-end and mobile application consume API (even at routes public). I think it’s something like a CSRF token, only that stateless.

2 answers

11

You will need some form of authentication between the client and the API. There are some possibilities that vary according to the degree of security you need.

If you want something trivial to implement, you can do a User-Agent or token check. Simply add the custom header to all requests made to the API; each application can have its specific UA/token. In Express, the check would be as simple as req.headers['user-agent'].match(/MeuUserAgentPersonalizado/). I usually identify native applications with the format PacoteApp/VersaoApp (NomeSistema; VersaoSistema; MarcaDispositivo; ModeloDispositivo).

If you need more security, I believe the best option is to use an authentication middleware, such as JSON Web Token - or JWT. There are alternatives to implementing this technique, such as using private keys (Keys Apis) embedded in applications; or using user-based authentication and password. The first will be more interesting if you are not offering user account functionality; the second is especially useful when you need to protect API methods or resources according to more granular rules (such as user access permissions).

I recommend some readings on the subject:


Updating:

As suggested in the comments by Paulo Victor, one possibility is to use the header Referer to authorize or deny the requisitions. It is important to note that it can set up privacy and security issues in web applications as explained in this article (in English) from MDN. Its implementation follows the proposed use of the User-Agent suggested in this response, so it suffers from the same weaknesses, since an attacker can intercept the request (a simple process to do with web applications) and view the headers, copying them with ease.

I suggest reading the discussion on this subject in the Software Engineering OS How to Safghanuard a REST API for only Trusted mobile Applications, I believe it’s the same problem you face.

DRT; If you don’t care about potential attackers trying to replicate requests from headers (which can be inspected in the browser or reverse engineered), use a combination of User-Agent, Referer or headers at your discretion. To make it difficult to reverse engineer, you can use dynamic values (such as combining secret app + HTTP Method/URL + timestamp) obfuscated via hash and checked in the API. I think that no alternative is completely safe having someone with abundant time and resources to try to violate it.

  • 1

    I do not think that answers the question. Your answer includes means of authentication. What I want is a means to make only the mine front-end and the mine application can consume the API (even without user authentication). I edited the question adding more details.

  • 1

    Got it. I’ll be updating my answer as soon as possible.

  • You can check the referrer and check if it’s your front-end domain. req.headers.referer

  • Updated response. If needed, we can discuss these (and other) security approaches in chat.

6

Any type of key, token or security you apply will need to be applied on the client side as well. And that’s the big problem. When we are talking about a web application, there are easy ways to inspect the browser and find that key or token. Already in a mobile app, the user can decompile their app and easily grab that key. If the connection between client and server does not use SSL, someone with a network monitor can view the requests.

The fact is, in your case, your API is public. The user does not need to previously log in to use it or anything like that. Just consult and requisition.

If someone really wants to hit your API from outside of your applications, they will succeed. No matter what techniques you add to prevent this, all that will happen is to make this work harder, but it is still possible.

What I usually do in public Apis is monitor. Cloud servers and services today already have tools to block and de-prioritize requests that are abusing your application. Guide your decisions according to what the dice show you. Monitor your application and see if there really is someone trying to do something they shouldn’t. If they are not, why worry so soon? And if they are trying, it is a good sign. Your application is already so famous that it is calling attention. When you get there, make the necessary arrangements: JWT, CORS, CSRF.

The only way to ensure 100% that your public API will not receive requests from outside is by making it private. Thus, you have control of 100% of the requisitors.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.