How to Implement Input Sanitization in Node.js Express
A step by step guide to adding input sanitization to a Node.js Express contact form using validator and isomorphic-dompurify
What You Will Build
By the end of this guide you will have a contact form that sanitizes and validates all user input on the server before doing anything with it. This protects against XSS attacks, URL injection, and malformed data.
Prerequisites
- A working Node.js Express application
- A contact form with fields for firstName, lastName, email, and comments
- A route that handles the form POST submission
- A helper module that contains your validation and email logic
Step 1 — Install the Required Packages
Open your terminal in your project root and run:
npm install validator isomorphic-dompurify
validator provides string validation and sanitization functions. isomorphic-dompurify strips malicious HTML from strings and works in Node.js on the server.
Step 2 — Update Your Contact Helpers Module
Open your contact helpers file (in this project it is modules/contact-helpers.js). Make the following changes.
At the top of the file, require both packages:
const validator = require('validator');
const DOMPurify = require('isomorphic-dompurify');
Replace your existing isValidEmailAddress function with this:
function isValidEmailAddress(email){
return validator.isEmail(email);
}
Add this new sanitizeInput function:
function sanitizeInput(str){
if(!str) return '';
str = validator.escape(str);
str = validator.stripLow(str);
str = DOMPurify.sanitize(str);
str = str.trim();
return str;
}
Add sanitizeInput to your exports at the bottom of the file:
exports.sanitizeInput = sanitizeInput;
Your full contact helpers file should look like this when done:
const validator = require('validator');
const DOMPurify = require('isomorphic-dompurify');
function isValidEmailAddress(email){
return validator.isEmail(email);
}
function containsURL(str){
var regExp = /\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i;
return regExp.test(str);
}
function sanitizeInput(str){
if(!str) return '';
str = validator.escape(str);
str = validator.stripLow(str);
str = DOMPurify.sanitize(str);
str = str.trim();
return str;
}
function isValidContactFormSubmit(firstName, lastName, email, comments){
if(firstName && lastName && email && comments){
if(containsURL(firstName) || containsURL(lastName) || containsURL(comments)){
return false;
}
if(!isValidEmailAddress(email)){
return false;
}
return true;
}
return false;
}
function sendEmailNotification(message, callback){
const nodemailer = require('nodemailer');
// ... your email config here
}
exports.isValidContactFormSubmit = isValidContactFormSubmit;
exports.sanitizeInput = sanitizeInput;
exports.sendEmailNotification = sendEmailNotification;
Step 3 — Update Your Express Route
Open app.js and find your contact form POST route. Make the following changes.
Update the require statement to include sanitizeInput:
const {isValidContactFormSubmit, sendEmailNotification, sanitizeInput} = require("./modules/contact-helpers");
After destructuring req.body, add sanitization for each field:
const {firstName, lastName, email, comments} = req.body;
const cleanFirst = sanitizeInput(firstName);
const cleanLast = sanitizeInput(lastName);
const cleanEmail = sanitizeInput(email);
const cleanComments = sanitizeInput(comments);
Pass the cleaned values to isValidContactFormSubmit and use them to build your message:
if(isValidContactFormSubmit(cleanFirst, cleanLast, cleanEmail, cleanComments)){
const message = `From: ${cleanFirst} ${cleanLast}\nEmail: ${cleanEmail}\nMessage: ${cleanComments}`;
// send email...
}
Step 4 — Test It
Start your server and submit the contact form with this in the comments field:
<script>alert('xss attack')</script>
Check the email you receive. The comments field should show:
<script>alert('xss attack')</script>
If you see the escaped version in the email, sanitization is working correctly. The dangerous characters have been converted to harmless HTML entities.
What Each Step Does
validator.escape converts <, >, &, ', ", and / to HTML entities. This is the primary defense against XSS.
validator.stripLow removes invisible control characters that have no place in form input.
DOMPurify.sanitize parses the string as HTML and removes any remaining executable code — script tags, event handlers, javascript: URLs.
.trim() removes leading and trailing whitespace.
These four operations run in sequence on every field before any other processing happens.