0
0
NodejsDebug / FixBeginner · 4 min read

How to Prevent XSS in Node.js: Simple and Effective Methods

To prevent XSS in Node.js, always sanitize user input and escape output before rendering it in HTML. Use libraries like DOMPurify or sanitize-html to clean input, and frameworks like helmet to set security headers that reduce XSS risks.
🔍

Why This Happens

XSS happens when an attacker injects malicious scripts into web pages viewed by other users. In Node.js apps, this often occurs when user input is directly included in HTML without cleaning or escaping, allowing harmful JavaScript to run in the browser.

javascript
const express = require('express');
const app = express();

app.get('/', (req, res) => {
  const userInput = req.query.name || '';
  res.send(`<h1>Hello, ${userInput}!</h1>`);
});

app.listen(3000);
Output
<h1>Hello, <script>alert('XSS')</script>!</h1> // This runs the alert script in the browser
🔧

The Fix

Fix this by escaping user input before adding it to HTML. Use libraries like escape-html or sanitize input with sanitize-html. This stops scripts from running by converting special characters to safe HTML entities.

javascript
const express = require('express');
const escapeHtml = require('escape-html');
const app = express();

app.get('/', (req, res) => {
  const userInput = req.query.name || '';
  const safeInput = escapeHtml(userInput);
  res.send(`<h1>Hello, ${safeInput}!</h1>`);
});

app.listen(3000);
Output
<h1>Hello, &lt;script&gt;alert('XSS')&lt;/script&gt;!</h1> // Script tags are shown as text, not run
🛡️

Prevention

Always validate and sanitize all user inputs on the server side. Use trusted libraries like sanitize-html or DOMPurify to clean HTML inputs. Set security headers with helmet to prevent injection attacks. Avoid inserting raw user data into HTML without escaping. Regularly update dependencies and use Content Security Policy (CSP) headers to restrict script sources.

javascript
const express = require('express');
const helmet = require('helmet');
const sanitizeHtml = require('sanitize-html');
const app = express();

app.use(helmet());

app.get('/', (req, res) => {
  const userInput = req.query.name || '';
  const cleanInput = sanitizeHtml(userInput);
  res.send(`<h1>Hello, ${cleanInput}!</h1>`);
});

app.listen(3000);
Output
Safe HTML output with scripts removed and security headers set
⚠️

Related Errors

Other common security issues include SQL Injection, where attackers inject database commands, and CSRF (Cross-Site Request Forgery), where unauthorized commands are sent from a user’s browser. Use parameterized queries to prevent SQL Injection and CSRF tokens to protect against CSRF attacks.

Key Takeaways

Always escape or sanitize user input before including it in HTML to prevent XSS.
Use security libraries like helmet, sanitize-html, or DOMPurify in Node.js apps.
Set Content Security Policy headers to restrict where scripts can load from.
Never trust raw user input; validate and clean all data on the server side.
Keep dependencies updated to patch known security vulnerabilities.