How to prevent others from using my REST API? - node.js

I've developed simple REST API using a expressJs. I'm using React as my client side application. So the problem is anyone can see my API endpoints because of react app is in client side. So they will also able to make request and fetch data from my REST API. (May be they will build their own client side apps using my API.) I've seen some question about this and couldn't find any comprehensive answer. How these kind of a security problem should be handled? Is it possible to give the access for API to only my client app? If not how huge brands that using REST API prevent that? (Also I don't have a user authenticating scenario in my product as well. People can just visit and use the website. They don't need to register).

Authentication can be a way but it can be bypassed. Another way is you can create a proxy server which strictly blocks cross origin requests, hence it blocks requests from other domains to make request to your API, and you can make your API call from that proxy server. In this way your API server endpoint will also be not compromised.

If, as you state in your comment, this is about users on your own website being allowed to use your site's API, while disallowing off-site use (e.g. other websites, wget/curl, etc) then you need to make sure to set up proper CORS rules (to disallowed cross-origin use of your API) as well as CSP rules (to prevent user-injected scripts from proxying your API), and you also make sure to only allow API calls from connections that have an active session (so even if you don't want user authentication: use a session managemer so you can tell if someone landed on your site and got a session cookie set before they started calling API endpoints).
Session management and CORS come with express itself (see https://expressjs.com/en/resources/middleware/session.html and https://expressjs.com/en/resources/middleware/cors.html), for CSP, and lots of other security layers like HSTS, XSS filtering, etc, you typically use helmet.

Related

Ways to secure API that do not require authentication, to be called only from one pre-defined consumer

I have currently developed a backend app that has some important functionalities. I want to consume my backend endpoints from my frontend but I want to be sure that only my fronted calls the backend endpoint and no other. Currently anyone that access my web-app can take advantage of the functionalities (I do not require any user registration or authentication).
How can I be safe that my backend is not being called form other possible malicious attackers that may try to steal the functionalities of my backend?
I have read some other posts regarding solutions how to secure a backend app that do not require user authentication but none has a precise and secure way for that. Some say enabling CORS but during my experience I can say that CORS can be manipulated easily with the help of a simple browser plugin. (not speaking about mobile apps that do not consider it at all)
I would really appreciate if I would have some opinions in case of a web-frontend-app, mobile app and other backend systems that would try to call my API and how can I stop them.
Typical front-end authentication would be best (OpenID, ...).
If you want something different, you could check on your backend whether a specific header with a specific token is sent in the query. If it is not then you send back a 401 HTTP code.
This requires that your customers somehow get that token (through some registration process, probably) and then keep it long-term (it can be stored in LocalStorage but can be lost when cleaning up the browser)
OWASP Authentication is a good source of information.

How to implement Security in Rest API developed using Node.JS?

I want to design a SPA which will have Frontend (React) and Backend-Rest API (Node.js, Express, Mongo DB). I am planning to have Single Sign-On in my application where users would be authenticating using MS-Azure AD, where a call would go to Azure AD from Frontend and in return I will get a token for that User which will be stored locally. After that, I want to call my rest API, for multiple GET, POST, PUT operations in the context of current user logged in on UI. Planning to deploy both frontend and backend on different servers so here I have two questions about securing my REST API.
CORS Implementation
User-Authentication on BE
Given the above requirements is it enough to have just CORS implemented or Do I need to again authenticate the User on BE?
Can somebody provide some best practice or experiences? Is there a lack in my “architecture”?
While CORS is definitely a consideration, it isn't Authentication (AuthN) or Authorization (AuthZ) which you need.
Depending on the number of users your application will have, how the back end will scale you might want to look at OAuth2.0 or stick with simpler session based auth but you will need something.
CORS on your back end will limit if a browser running an app on a domain other than yours to call your web services (it wont stop API requests from other tools).
AuthN - Your not logged in - go get logged in and come back to
me.
AuthZ - Controls what your users can and cant do. You might want to
enforce this at the resource level but you absolutely need to within
your business logic.
Further reading https://auth0.com/docs/authorization/concepts/authz-and-authn
Philippe from Pramgmatic web security has a free online course to get you started: https://pragmaticwebsecurity.com/courses/introduction-oauth-oidc.html Its very well paced and should give you some foundational knowledge. (It might let you write off OAuth for this use case but give it a go)
CORS will not perform any user authentication. You need CORS only when your client code is served from another domain than the backend you are talking too. If it is the same server to host static client files and backends REST endpoint, you don't need CORS. If you are unsure, then don't consider CORS at all and see if it works.
But you need authentication to know which user is which.

nodejs API restrictions ... Not allowed from postman .. same origin access allowed

I have created few API on nodejs a d want to consume in same nodejs app. Even I have ensure cross origin to my domain.
It's only preventing cross domain and not allowed API.
But when using postman it's allowed .
Please help to provide how to restrict my nodejs api to be used by my app internal in angular and should not allow cross domain and postman.
Cross domain protections are implemented only in a browser to protect end-user browser security. They do not apply to http requests made from Postman or from node.js or from any other programmatic tool, only from the browser.
There is no way to keep your API from being called by other agents besides your own web app. This is just the way of the web. For your web page to be able to use the API in the browser, that API has to be open to the public.
The usual way to provide some protections on such APIs is to require some sort of user login in order to use the API. Your own web app can have a logged in user and your server can require a certain login cookie be on the http request before your server will fulfill the request. This too can be used by 3rd party tools such as Postman, but they would have to first obtain an appropriate login cookie.
To prevent abuse even in these cases where they get a login cookie, you would need to track usage on your server and if you detect any irregular patterns or abusive patterns (often with some sort of rate limiting detection logic), then you can temporarily or permanently ban that user login.

Setup API that only your webserver can see it

So I want to have nginx serve up my react app that uses an API that is setup to make all the API calls for me. I want to do this so I can guard my API key and secret. So the API server is running on port 9001 and my react app is making api calls to to http://localhost:9001/api/v1/token. It works just fine. The issue I have is, how can I stop someone from doing the following to get a token?
curl -X POST --header "referer: http://localhost:8081" -i http://localhost:8081/api/v1/token
Thanks
If what you're asking is how you allow only your react app to use your API server, then the answer is you can't really.
Any request made from the browser has to be made to a server that can be reached lots of other ways (such as your Curl example). You can't allow only requests made from your React code and disallow all other attempts to talk to your API server because at the lowest level, these are all just http requests. Any determined hacker can just watch what the browser sent from your React app and make an http request that looks just like it. This is a fundamental design characteristic of how apps in a web browser work.
That said, there are some things you can do to "protect" your API server from abuse.
1. Require some form of account or authentication. This will at least require a hacker to make an account in your system and use that account to access your API server (more on this later).
2. Implement rate limiting so that an individual account (detected based on the credentials in the previous step) is only allowed certain frequency or pattern or access. At the very least this protects your API server from being overly abused by one bad actor.
3. Implement abuse control. If one particular account is regularly abusing the API server (hitting rate limit controls and generally using way more resources on your API server than any reasonable normal browser user ever would), then you can ban that account.
Services such as Google maps implement all three of the above in their efforts to protect the integrity of their API servers.
There are other techniques such as embedding an ever changing token into the web page that is then required with each subsequent call to the API server, but a determined hacker will just scrape the token from the web page and then use it until it expires so this is really just another obstacle for the hacker to get around, not an actual roadblock.

Magento to NodeJS via REST APIs using OAuth

I'm trying to call one of Magento REST APIs (say products api) from a NodeJS application using a regular HTTP Request. I know that Magento APIs requires OAuth to authenticate the user/application, and this is where I'm a bit lost.
With Magento or any OAuth application, the end-user who is using the app has to click "Authorize" in order for that application to receive the token, and then the application will be able to communicate directly with Mangento APIs.
In my case, we are talking about 2 servers, Magento and NodeJS, that will talk to each other. So There is no user involve to sort of "Click" the authorize button and validate the auth request.
The point of what I'm trying to achieve is grab product data from Magento, store it in a DB, then make some changes, after that make it accessible via NodeJS REST APIs. (That is a hard requirement and I can't change it).
My question is, Do we have to write custom Magento REST APIs that doesn't require OAuth, or maybe require the regular basic HTTP Authentication (username/password). Or there is a way to use OAuth and authenticate my Node application directly?
I hope my question is clear, if not please let me know and I will try to fix it. Thanks!
After wrestling with a similar situation, I decided to use Magento's SOAP API. All you have to do as far as authentication goes is to set up an API user in the Magento backend and then use the username/password in your API calls (I think, it's been awhile). Not sure if this fits your use case but it saved me a lot of OAuth headache.

Resources