Prevent node xss sanitizer on specific post requests

Viewed 561

Context is a node express api, I'm using xss-clean on my main server.js file:

const xss = require('xss-clean');

// Prevent XSS attacks
app.use(xss());

Problem: I want to save rich text, but it's destroyed during sanitation.

I want to keep this functionality globally, however it prevents me from saving rich text via rich text editors on the front end (ie tiptap-vue). The text saved with editor contains html markup, which is escaped when saving to the database, and when pushed back out to the front end via a get request the text reads out with the escapes and the element's markup.

Is there a way to prevent this global component from working on one specific request, or specific data within a request?

or is there a way to un-escape it for use on the front end?

1 Answers

You could simply modify the middleware from your own node_modules folder, and in the source-code file where it begins to parse the request object, you could add conditional logic that checks if the request object meets the conditions you're checking for-- whether it's a specific request or contains the specific data within the request-- and then decide whether or not you use the sanitization function on the request object.

[Unmodified] xss-clean/src/index.js:

import { clean } from './xss'

/**
 * export middleware
 * @return {function} Middleware function
*/
module.exports = function () {
 return (req, res, next) => {
   if (req.body) req.body = clean(req.body)
   if (req.query) req.query = clean(req.query)
   if (req.params) req.params = clean(req.params)

   next()
 }
}

To

import { clean } from './xss'

/**
 * export middleware
 * @return {function} Middleware function
*/
module.exports = function () {
 return (req, res, next) => {
   if (req.url === "your route path") {
     //don't use clean() on request object OR you can store only the data you want 
     //in a temp variable to avoid getting sanitized, then sanitize the request 
     //object with clean(), and then replace that sanitized data with the data
     //in the temp variable OR as a new property in the req object
     const dataPoint = req.body.something.dataPoint;
     req.body = clean(req.body);
     req.body.something.dataPoint = dataPoint;
      
     return next();
   }

   if (req.body) req.body = clean(req.body)
   if (req.query) req.query = clean(req.query)
   if (req.params) req.params = clean(req.params)

   next()
 }
}

This is a bit hacky, but does the job. It's dangerous to not sanitize unless you know for sure it's not going to be an issue. You could also simply not use this middleware globally in your application, and use it only on the routes you want this middleware to sanitize.

Related