Security in Node.JS and Express: The bare minimum - Part 3.
Tags: javascript, node, security, webdev
Published: 2020-04-15 14:27:56

---
title: Security in Node.JS and Express: The bare minimum - Part 3. 
published: true
description: Easy ways to secure an Express application
tags: #javascript #node #security #webdev
---

In the previous part, we covered
* XSS Attacks
* SQL injections
* RegEx Denial of Service


{% post https://dev.to/demetrakopetros/security-in-node-js-and-express-the-bare-minimum-part-2-ll4 %}

In this part, we will cover
* Cross-Site Request Forgery Attacks (CSRF)
* Rate Limiting 
* Data Sanitization

# Cross-Site Request Forgery

Cross-Site Request Forgery according to [OWASP](https://owasp.org/www-community/attacks/csrf)
> Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they’re currently authenticated. CSRF attacks specifically target state-changing requests, not theft of data, since the attacker has no way to see the response to the forged request. 

In order to prevent this kind of attacks, we should implement a **synchronized CSRF tokens policy**.

CSRF token is a simple string set when the user requests a page that contains a form and expects the same CSRF token when a POST request is made. If the CSRF tokens do not match or if the CSRF token is not in the form data, the POST request is not allowed. CSRF token is **unique for each user session** and most of the times it expires in a given time span.

In Express applications we can implement a CSRF policy with the help of [csurf](https://www.npmjs.com/package/csurf) npm package. 
The package can be used in one line and it handles everything related to the CSRF tokens for all the users.

So in the back-end the correct setup looks like this
```Javascript
var csrf = require('csurf');
var app = express();
app.use(csrf());

app.use(function(req, res, next) {
  res.locals._csrf = req.csrfToken();
  next();
});
```
And in the front-end looks like this for each form.

```HTML
<html>
  <form method="post" action=“changeEmail">
    <input type="hidden" name="_csrf" value="_csrf">
    <input type="email" name=“newEmail">
  </form>
</html>
```

# Rate Limiting

One other crucial aspect of the security of your Express application is **rate limiting**. As you may already know, rate limiting is the policy that control the rate of requests that your server can receive from a specific user and / or IP address. In that way we prevent [DoS attacks](https://en.wikipedia.org/wiki/Denial-of-service_attack).

[express-rate-limit](https://www.npmjs.com/package/express-rate-limit) npm package enables us to apply policies like the ones mentioned above in a really easy way.

i.e
```Javascript
var rateLimit = require("express-rate-limit");
 
 app.set('trust proxy', 1); // add this line only if your server is behind a proxy
 
var limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // limit each IP to 100 requests per windowMs
delayMs: 0 // disable delaying - user has full speed until the max limit is reached
});
 
app.use(limiter); // applies rate limiting policy to every endpoint of the server
// we could also apply policies for specific routes or even different policies for each route
```
[express-rate-limit](https://www.npmjs.com/package/express-rate-limit) allows us to apply rate limiting policies to all the endpoints of our Express server or even different policies for each route.

i.e This example applies a rate limiting policy only to the enpoints starting with /api.
```Javascript
var rateLimit = require("express-rate-limit");
var apiLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100
});
 
// only apply to requests that begin with /api/
app.use("/api/", apiLimiter);
```

**Important note:** Static resources such as images, CSS stylesheets, front-end Javascript scripts count for requests as well **if we serve them through our Express server** (which is a bad practice anyway, we should prefer CDN networks for static resources).

# Data sanitisation and validation

It is an important process that must take place in every endpoint where the user interacts with the server **by submitting data**. It protects the server from most of the flaws mentioned in this serie of articles. When we are validating data, we are interested in checks like **"Is this a correct e-mail address?"**, **"Is it an Integer?"**, **"Is it a valid telephone number?"** etc.

A very usefull npm package that helps us perform this kind of checks in user input is [express-validator](https://www.npmjs.com/package/express-validator).

[express-validator](https://www.npmjs.com/package/express-validator) allows us to define "check schemas" for each endpoint in pure JSON. It also allows us to set the error messages sent back to the user if a validation for a field fails.

An example is given below:
```Javascript
app.put('/user/:id/password', checkSchema({
   id: {
   // the location of the field can be one or more of 'body', 'cookies', 
   'headers', 'params' or 'query'.
   // If omitted, all request locations will be checked
     in: ['params','query'],
     isInt: true,
     errorMessage: 'ID is wrong'
   },
   password: {
      isLength: {
         errorMessage: 'Password should be at least 7 characters long',
         options: {min: 7}
      }
   }
})
```

express-validator offers many useful keys and functions such as `isIn()`, `exists()`, `isUUID()`, `isPostalCode()`, trimimng functions etc. It also allows us to implement custom validation and sanitisation logics.

# That's all folks (for now...)
I hope you find it interesting and it will help you build more secure and robust Node.JS and Express apps.