Easy steps to make your Node.js express app a lot more secure🔐

In this post, we will look into how to increase the security of the node.js express app in preventing DOS, XSS, SQL injections, and brute force attacks easily by using specific packages.

Preventing DOS Attacks

DOS attacks will crash the server, which makes the API's inaccessible. For example, the attacker sends plenty of requests and large amounts of data to overwhelm and exhaust the system resources which will lead to a server crash.

Rate-limiting

Rate limiting is a very powerful feature for securing backend APIs from malicious attacks and for handling unwanted streams of requests from users. You can rate limit your API's by using this simple npm package express-rate-limit.

const express = require('express');
const rateLimt = require('express-rate-limit');

const app = express();

const limiter = rateLimit({
    windowMs: 20 * 60 * 1000, // 20 minutes
    max: 100 // limit each ip to 100 requests per windowMs
});

app.use(limiter);

Limit the Body payload

In this type of attack, the server is sent a large payload, which the server then attempts to decode, but is compelled to use an excessive amount of memory, thus overwhelming the system and crashing the service. We can restrict the size of the payload by using the body-parser and also we can restrict it in a web server like Nginx.

const bodyParser = require('body-parser')
app.use(bodyParser.json({ limit: "1mb" }))

Preventing XSS Attacks

Untrusted data that is sent down to the browser might get executed instead of just being displayed, this is commonly being referred to as a cross-site-scripting (XSS) attack.

Data Validation and sanitization

Always perform input data validation and sanitization, use XSS or xss-clean

const xss = require('xss-clean')
// Make sure that this comes before any other routes
app.use(xss())

Headers

The Content Security Policy you can apply the HTTP Content-Security-Policy (CSP) header to prevent unauthorized code execution. CSP supports many directives that help you to control how content can be combined in your HTML page. You can use the helmet to set up the appropriate header

const helmet = require('helmet')
app.use(helmet())

Helmet enables the following HTTP headers.

  • Strict-Transport-Security
  • X-frame-Options
  • X-XSS-Protection
  • X-Content-Type-Protection
  • Content-Security-Policy
  • Cache-Control
  • Expect-CT
  • Disable X-Powered-By

These headers prevent malicious users from various types of attacks such as clickjacking, cross-site scripting, etc.

Preventing SQL/NoSQL Injections

To prevent SQL/NoSQL injection and other malicious attacks, always make use of an ORM/ODM or a database library that escapes data or supports named or indexed parameterized queries, and takes care of validating user input for expected types. Never just use JavaScript template strings or string concatenation to inject values into queries as this opens your application to a wide spectrum of vulnerabilities. All the reputable Node.js data access libraries (e.g. Sequelize , Knex , mongoose ) have built-in protection against injection attacks

Preventing Brute Force Attacks

  • The most efficient way is to limit the number of login attempts.
  • Use Bcrypt to encrypt the passwords, which will slow down the attacker when guessing.
  • You could use express-rate-limit, which works for both DOS attack and brute force attack.
  • Implement 2 step verification.

Check dependencies

With the npm ecosystem, it is common to have many dependencies for a project. Dependencies should always be kept in check as new vulnerabilities are found. Use tools like npm audit, nsp, or snyk to track, monitor and patch vulnerable dependencies. Integrate these tools with your CI setup so you catch a vulnerable dependency before it makes it to production.

No Comments Yet