Sanitizing and Validating data in Node.JS Express App

Sanitizing and Validating data in Node.JS Express App

Using "express-validator" to sanitize and validate user input

When you have an app that accept input from the outside, you can't always trust the input. There maybe typos, mix-up with the fields or some users may even try to inject malicious code into the input. That is why it's important to sanitize and validate your data before using them or storing them in a database.

Sanitizing --> Sanitizing is the process of modifying the data to make sure it is safe to use by removing harmful or unwanted characters. This will work as one of the basic defenses against code injections and unexpected code executions.

Validating --> Validating checks to see if the data is in the correct format. It checks to make sure we are getting the expected data(eg- ensuring that the user input is really an email, etc.)

Usually, you want to have a combination of both, first sanitize the data and then validate it. There are different packages/modules available depending on the programming language and framework to do this. I will go over how to handle it for an express app using the most commonly used 'express-validator' package.

Basic setup

To start, I'll assume that you already have express and express validator installed. Our application will be created inside app.js and I have already created a simple template to begin.

const express = require('express');

const app = express();
app.use(express.json());

app.get('/home', (req, res) => {
    res.send("Welcome to the home page");
});

app.listen(5000);

There are several ways for us to get user input, and they can be accessed within the following request locations,

Type of dataLocationValidation function
Formsreq.bodybody()
URL Parametersreq.paramsparam()
Request Headersreq.headersheader()
Cookiesreq.cookiescookie()
Queriesreq.queryquery()

The validation functions can be imported from express-validator as follows:

const { body, param, header, cookie, query } = require('express-validator');

Thus, our complete code looks like this:

const express = require('express');
const { body, param, header, cookie, query } = require('express-validator');

const app = express();
app.use(express.json());

app.get('/home', (req, res) => {
    res.send("Welcome to the home page");
});

app.listen(5000);

We can use these functions as middleware to sanitize and validate our data.

Sanitizing data

If we are getting an 'email' field in our req.body, we can use the escape() method to sanitize it.

//...

app.get('/home', body('email').escape(), (req, res) => {
    res.send("Welcome to the home page");
});

//...

Validating data

After we have sanitized the data, we can validate to see if it really is an email. To do this, we can create a validation chain. A validation chain would look like this:

//...

app.get('/home', body('email').escape().isEmail(), (req, res) => {
    res.send("Welcome to the home page");
});

//...

We can of course create a longer chain with more validators, and for other fields as well:

//...

app.get('/home',
    body('email').escape().trim().notEmpty().isEmail(),
    body('password').escape().trim().notEmpty().isLength({min: 8}),
    (req, res) => {
        res.send("Welcome to the home page");
});

//...

Here, we are validating for both 'email' and 'password' fields.

trim() will remove white-space, then we use notEmpty() to check if the input is empty after the white-space was removed.

isLength({min: 8}) ensures that the password is at least 8 characters long.

"express-validator" uses validatorjs for it's functionality. So, you can find all the available validators here.

Validation Errors

Let's say that we were validating for an email, but the user input was "myemail.gmail.com". This is clearly not a valid email, so the validation will give an error. But "express-validator" will not console.log() the error. To access the error, we need to use validationResult function, which would return an array of objects, which contains each error.

//...
const { body, validationResult } = require('express-validator');

app.get('/home', body('email').escape().isEmail(), (req, res) => {
    const results = validationResult(req);
    if(results.isEmpty()){
        return res.send("Welcome to the home page");
    }
    res.send("Validation Error!");
});

//...

Here, we are checking if the results array is empty( results.isEmpty() ). If it is empty, that means there weren't any issues and the validation was a success. Thus, we are returning the welcome message.

If the results array is not empty, that means there were errors. Which is why we're sending the error message.

The error objects returned by the validationResult would take the following format:

{
    "location": "body",
    "msg": "Invalid value",
    "path": "email",
    "type": "field"
}

Conclusion

It is extremely important that you validate any and all user input before using it in the app or storing it in a database. You can never know what type of data you're getting, so this will act as a basic line of defense against any malicious actors or from any unexpected errors that could occur.

If you have any questions or any feedback, please leave a comment. I'll be sure to answer it. I'm new to blogging, so if there are any parts that I didn't explain properly, let me know, I'll do my best to clarify them.

And if you want more short tutorials like this, make sure to follow me and also consider subscribing to my Newsletter. I will be posting extra articles there soon.

What's next?

This was only a short tutorial to go over the basics of sanitizing and validating data. You can check the official "express-validator" DOCs for more information.

If you want to know how to store your data in database after you have validated them, check my post on using Mongoose to store data in a MongoDB database with express.