express-xss-sanitizer
Version:
Express 4.x and 5.x middleware which sanitizes user input data (in req.body, req.query, req.headers and req.params) to prevent Cross Site Scripting (XSS) attack.
63 lines (54 loc) • 1.84 kB
JavaScript
;
const sanitizeHtml = require('sanitize-html');
function hasOwn(object, key) {
const keys = Reflect.ownKeys(object).filter((item) => typeof item !== 'symbol');
return keys.includes(key);
}
const initializeOptions = (options) => {
const sanitizerOptions = {};
if (hasOwn(options, 'allowedTags') && Array.isArray(options.allowedTags) && options.allowedTags.length > 0) {
sanitizerOptions.allowedTags = options.allowedTags;
}
if (hasOwn(options, 'allowedAttributes') && Object.keys(options.allowedAttributes).length > 0) {
sanitizerOptions.allowedAttributes = options.allowedAttributes;
}
return {
allowedKeys: (hasOwn(options, 'allowedKeys') && Array.isArray(options.allowedKeys) && options.allowedKeys) || [],
sanitizerOptions,
};
};
const sanitize = (options, data) => {
if (typeof data === 'string') {
return sanitizeHtml(data, options.sanitizerOptions);
}
if (Array.isArray(data)) {
return data.map((item) => {
if (typeof item === 'string') {
return sanitizeHtml(item, options.sanitizerOptions);
}
if (Array.isArray(item) || typeof item === 'object') {
return sanitize(options, item);
}
return item;
});
}
if (typeof data === 'object' && data !== null) {
Object.keys(data).forEach((key) => {
if (options.allowedKeys.includes(key)) {
return;
}
const item = data[key];
if (typeof item === 'string') {
data[key] = sanitizeHtml(item, options.sanitizerOptions);
} else if (Array.isArray(item) || typeof item === 'object') {
data[key] = sanitize(options, item);
}
});
}
return data;
};
const prepareSanitize = (data, options = {}) => {
options = initializeOptions(options);
return sanitize(options, data);
};
module.exports = prepareSanitize;