Best Practices for Securing Node.js Applications in Production
In this guide, you will see the 15 best practices for devising a secure Node.js app architecture for production. Implement them all to make your backend more secure than ever!
Why Should You Build a Secure Node.js App?
Building a secure Node.js application is important for at least three good reasons:
- Protecting User Data: Your application may handle sensitive user information such as personal details, login credentials, payment data, or confidential business insights. Failing to protect this data can cost you millions in fines from privacy regulators. By implementing robust security measures, you can safeguard user data and avoid legal issues.
- Safeguarding Application Functionality: Security vulnerabilities can compromise the features offered by your backend. Attackers may exploit weaknesses to alter your services, manipulate data, or inject malicious code. By securing your app, you can avoid that and provide a seamless experience for your users.
- Preserving Reputation: A security incident can seriously damage your reputation and erode trust in your service. Customers and users expect their data to be handled securely and your application to work as intended. A breach can lead to a loss of trust, but by prioritizing security you show your commitment to quality.
You might think that security problems are not that widespread and it is enough to follow coding and architectural best practices, but this is not true. The power of Node.js lies in the NPM environment, which offers millions of libraries. The problem is that most NPM packages involve some security vulnerabilities.
In other words, your Node.js project is not safe if its dependencies are not. Considering how popular it is to use external libraries, this is worrisome. According to the Snyk State of Open Source Security report, an average Node.js project has 49 vulnerabilities out of 79 direct dependencies. That concerning statistic underscores how important it is to protect your Node.js application.
15 Best Practices to Make Your Node.js App More Secure
Let’s take a look at the most popular best practices to secure your Node.js project.
1. Never Run Node.js With Root Privileges
Running Node.js with root privileges is not recommended as it goes against the principle of least privilege. No matter if your backend is on a dedicated server or Docker container, you should always launch it as a non-root user,
If you instead run Node.js with root privileges, any vulnerabilities in your project or its dependencies can potentially be exploited to gain unauthorized access to your system. For example, an attacker could harness them to execute arbitrary code, access sensitive files, or even take control of the entire machine. Thus, using root users for Node.js must be avoided.
The best practice here is to create a dedicated user for running Node.js. This user should have only the permissions required to launch the app. This way, attackers who succeed in compromising your backend will be restricted to that user’s privileges, limiting the potential damage they can cause.
2. Keep Your NPM Libraries Up To Date
NPM libraries make it easier and quicker to build a full-featured Node.js backend. At the same time, they can also introduce security risks into your application. New vulnerabilities are discovered all the time, and it is the maintainers’ job to address them and release an updated version of the package. Here is why you should keep your dependencies up to date.
To ensure the NPM libraries you are relying on are secure, you can use npm audit and snyk. These tools analyze your project’s dependencies tree and provide insights into any known vulnerabilities.
Here’s an example of running npm audit:
npm audit
...
found 4 vulnerabilities (2 low, 2 moderate)
run `npm audit fix` to fix them, or `npm audit` for details
This command leverages the GitHub Advisory Database and checks your package.json and package-lock.json against known security issues.
Additionally, you can use Snyk to check your dependencies against Snyk’s Open Source Vulnerability Database. Install snyk with:
npm install -g snyk
In the root folder of your project, test your application with:
snyk test
To open a wizard that will walk you through the process of patching the vulnerabilities found, run:
snyk wizard
Using snyk and regularly running npm audit helps you identify and fix security issues in your NPM libraries before they might become a problem. Remember that the security of your app is only as strong as the weakest link in your dependencies.
3. Avoid Using Default Cookie Names
The cookie names used by your Node.js application can unintentionally reveal the technology stack your backend is based on. That is valuable information that you should always obscure, as attackers can use it again you. By knowing what framework you are using, they can exploit specific weaknesses associated with it.
In detail, attackers tend to focus on the name of the session cookie. Protect your app from that by setting a custom session cookie name with the express-session middleware:
const express = require('express');
const session = require('express-session');
const app = express();
app.use(session({
// set a custom name for the session cookie
name: 'myCustomCookieName',
// a secure secret key for session encryption
secret: 'mySecretKey',
}));