How to implement Security in Rest API developed using Node.JS? - 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.

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 prevent others from using my REST API?

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.

How do I secure rest api?

I'm working an app with Angular.I want to get the data to be listed from rest api. However, I don't want users to access the resource. Which language, library or framework can I secure it with? And users are using the app without membership.
I tried jwt but I didn't get the result I wanted. Maybe I couldn't.
Here is express.js
const app = require('express')()
const express = require('express')
const fs = require('fs')
const cors = require('cors')
const bodyParser = require('body-parser');
app.use(cors())
app.use(bodyParser.json())
app.get('/', (req, res) => {
res.json({message: 'Rest API Work'})
})
app.get('/list', (req, res) => {
fs.readFile('data1.json','utf-8',(err,data)=>{
res.setHeader("Content-Type", "application/json; charset=utf-8")
data = JSON.parse(data)
console.log(data)
res.end(JSON.stringify(data,null,4))
})
})
app.listen(3002, function(){
console.log('Server OK')
})
I want a simple security method where I can connect with Angular.
Best way to secure your API is start using a reverse proxy like Nginx. Javascript frameworks are all basically the same in terms of security. They all have a basic router handler, dispatcher (based of native Node.js HTTP library) and some basic helper methods, they give it a nice catchy name and that's it. I've checked the source code of almost all major frameworks.
Now, some basic configuration params of Nginx are: client_body_buffer_size proxy_buffers etc. All your directives should regex input data too. Generally anything that could "filter" the malicious code is useful. Cloudflare can somehow help and some other companies that could secure your app but they're expensive.
Another good example is containerizing your app using Docker.
If you have a basic piece of code in Node.js, the most easy way to hack it is through your app's logic. You should use anti-XSS modules like xss or express-sanitizer. If you're using SQL database you should always escape the query values.
ASSUMPTIONS
I'm working an app with Angular.
I am assuming that you are doing a Web App, and not a mobile app with something like NativeScript.
I want to get the data to be listed from rest api. However, I don't want users to access the resource
I assume here that you want that only the web app to have access to the API, and not anyone else.
LETS TACKLE YOUR QUESTIONS
Which language, library or framework can I secure it with?
The problem is not the programming language or framework, but what you are trying to achieve, and I honestly have to tell you a cruel truth... In the context of the web is not possible to lock down an API to a Web app, and this is just because of the way the web was built, you know you hit F12 and you can see all the code running in the browser, therefore any secret you put there to identify your web app in each request it does to the API, will be up for grabs and reuse by anyone who wants to replicate your web app, and your API will not be able to distinguish the WHO is doing the request from WHAT is doing the request.
And users are using the app without membership.
Contrary to what many developers may think, authenticated users don't lock-down a web app or mobile app to the API server, because the user is only one part of the equation, he represents the WHO is accessing the API, but you still need to address WHAT is accessing it.
Wait, wait a second... You keep referring to the WHO and the WHAT, do you care to explain it in more detail?
Glad you asked ;)
The Difference Between WHO and WHAT is Accessing the API Server
So let's clear a common misconception, among developers, about WHO and WHAT is accessing an API server.
To better understand the differences between the WHO and the WHAT are accessing an API server, let’s use this picture:
So replace the mobile app by web app, and keep following my analogy around this picture.
The Intended Communication Channel represents the web app being used as you expected, by a legit user without any malicious intentions, communicating with the API server from the browser, not using Postman or using any other tool to perform a man in the middle(MitM) attack.
The actual channel may represent several different scenarios, like a legit user with malicious intentions that may be using Curl or a tool like Postman to perform the requests, a hacker using a MitM attack tool, like MitmProxy, to understand how the communication between the web app and the API server is being done in order to be able to replay the requests or even automate attacks against the API server. Many other scenarios are possible, but we will not enumerate each one here.
I hope that by now you may already have a clue why the WHO and the WHAT are not the same, but if not it will become clear in a moment.
The WHO is the user of the web app that we can authenticate, authorize and identify in several ways, like using OpenID Connect or OAUTH2 flows.
OAUTH
Generally, OAuth provides to clients a "secure delegated access" to server resources on behalf of a resource owner. It specifies a process for resource owners to authorize third-party access to their server resources without sharing their credentials. Designed specifically to work with Hypertext Transfer Protocol (HTTP), OAuth essentially allows access tokens to be issued to third-party clients by an authorization server, with the approval of the resource owner. The third party then uses the access token to access the protected resources hosted by the resource server.
OpenID Connect
OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. It allows Clients 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 interoperable and REST-like manner.
While user authentication may let the API server know WHO is using the API, it cannot guarantee that the requests have originated from WHAT you expect, the browser were your web app should be running from, with a real user.
Now we need a way to identify WHAT is calling the API server, and here things become more tricky than most developers may think. The WHAT is the thing making the request to the API server. Is it really a genuine instance of the web app, or is a bot, an automated script or an attacker manually poking around with the API server, using a tool like Postman?
For your surprise, you may end up discovering that It can be one of the legit users manipulating manually the requests or an automated script that is trying to gamify and take advantage of the service provided by the web app.
Well, to identify the WHAT, developers tend to resort to an API key that usually is sent in the headers of the web app. Some developers go the extra mile and compute the key at run-time in the web app, inside obfuscated javascript, thus it becomes a runtime secret, that can be reverse engineered by deobusfaction tools, and by inspecting the traffic between the web app and API server with the F12 or MitM tools.
The above write-up was extracted from an article I wrote, entitled WHY DOES YOUR MOBILE APP NEED AN API KEY?. While in the context of a Mobile App, the overall idea is still valid in the context of a web app. You wish you can read the article in full here, that is the first article in a series of articles about API keys.
Now you may ask... If I can not lock down the API server to my web app only, how can I defend it?
Defending an API Server
To start with a web app or even a mobile should only communicate with an API server that is under your control and any access to third part APIs services must be done by this same API server you control. This way you limit the attack surface to only one place, where you will employ as many layers of defense as what you are protecting is worth.
So anything that runs on the client side and needs some secret to access an API can be abused in different ways and you can learn more on this series of articles about Mobile API Security Techniques. While this articles are in the context of an API serving a mobile app, some of the content are applicable for an API serving a web app to, and will help you to understand how fragile an API is when it comes to distinguish from WHO and WHAT is accessing it. So this series of articles will teach you how API Keys, User Access Tokens, HMAC and TLS Pinning can be used to protect the API and how they can be bypassed.
Now that you are more aware of the pains of defending an API server, let's see what can be done to mitigate the security risks is facing in the context of a web app. For an API serving a web app, you can employ several layers of dense, starting 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 the 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 these 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 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 these solutions require constant monitoring to validate that the false positives are not blocking your legit users and that at the same time they are properly keeping at bay the unauthorized ones.
CONCLUSION
I want a simple security method where I can connect with Angular.
So as may have realized already, you are not able to achieve a simple security method to lock down your Angular app with the API server. That's it, a simple security method does not do the trick, and instead you need to resort to several solutions, that will reduce the attack surface, but will not eliminate it.
So In the end, the solution to use in order to protect your API server must be chosen in accordance with the value of what you are trying to protect and the legal requirements for that type of data, like the GDPR regulations in Europe.

Restrict usage of Heroku app by Authentication?

I developed my Heroku app that exposes APIs only (no UI) and it works fine.
But how can I restrict the APIs to certain authorized/authenticated users only?
I absolutely need an authentication layer to protect the app APIs and prevent unauthorized accesses. A sort of login(user, psw) call to use before an external system can start invoking my API.
But I don't find any reference in the docs, it only says that these are the main security best practices:
Heroku SSL
Force the use of HTTPS
Trusted IP Range
Any idea?
That's something you'll need to implement at the application layer and not something that Heroku provides. At it's simplest you could implement basic auth in your app so that the user would pass them with their request, a more complex solution would involve user accounts and oauth etc etc.
You could implement all the authentication logic directly in your app.
Alternatively, take a look Auth0, which basically provides you with authentication and identity management as a service. You can easily add Auth0 to your Heroku app as a free add-on via the Heroku Elements marketplace.
They have lots of different use-cases and associated walk-throughs, and they offer a very generous free-tier.
From your requirements, it sounds like you might want to look at Auth0 Machine to Machine applications, using the OAuth2 Client Credentials Grant. With that, your external system(s) would basically need to authenticate with Auth0 using a Client Id and Client Secret (that you could generate in Auth0 and supply to them). Then, they would access your API with a JWT that you could easily validate in your app (Auth0 will provide you with generated code in many different languages for you to do that very easily). Your API will then reject requests without a valid JWT (by sending a "401 Unauthorized" response).
This may all sound a little intimidating at first, but it's really worth going through the relevant Auth0 "quickstart". They really go out of their way to try to make it as easy as possible!

Securing server with clientside javascript

I have a site that runs with a NodeJS backend and a ReactJS frontend. All of the frontend logic takes place in the user's browser, and the frontend hits backend routes to get business logic. Currently, we authenticate users with passportjs. But, when the user logs in, he or she can still use something like Postman to hit all of the backend routes, many of which should be private. Is there a good way to make sure that only an admin or our platform can hit our backend routes? I think this would require some kind of admin privilege that is always given to the frontend logic, but I was wondering if there is a best practice.
Unfortunately, after passport (or other auth) on the client there's very little you can do to facade your services without establishing additional identities.
This is more in the app arch/design realm, so hopefully you're not too far along to refactor. If not, then I would suggest abstracting your services so you can secure them more granularly. E.g. layer your services so you can establish identity before making calls to certain private/secured business logic. A framework like this might do the trick: http://loopback.io/

Resources