UNPKG

express-shield-securekit

Version:

A modular security middleware toolkit for Express.js with built-in rate limiting, SQL injection protection, and XSS sanitization.

99 lines (87 loc) 2.48 kB
import { Request, Response, NextFunction } from "express"; import xss, { IWhiteList, IFilterXSSOptions } from "xss"; import sqlString from "sqlstring"; import { sendResponse } from "../utils/responseHandler" const safeWhitelist: IWhiteList = { a: ["href", "title", "target"], b: [], i: [], strong: [], em: [], p: [], ul: [], li: [], ol: [], br: [], span: ["style"], h1: [], h2: [], h3: [], h4: [], h5: [], h6: [], }; const xssOptions: IFilterXSSOptions = { whiteList: safeWhitelist, stripIgnoreTag: true, stripIgnoreTagBody: ["script", "iframe", "object", "embed"], }; interface SanitizationError { key: string; value: any; sanitizedValue: any; type: "XSS" | "SQL Injection"; } export const sanitizeMiddleware = ( req: Request, res: Response, next: NextFunction ): void => { const errors: SanitizationError[] = []; const sanitizeAndDetect = (value: string, key: string): string => { // 1. XSS Protection const xssSanitized = xss(value, xssOptions); if (xssSanitized !== value) { errors.push({ key, value, sanitizedValue: xssSanitized, type: "XSS" }); } // 2. SQL Injection Detection (basic patterns) const sqlInjectionPattern = /('|--|\b(SELECT|UPDATE|DELETE|INSERT|DROP|UNION|OR)\b)/i; if (sqlInjectionPattern.test(value)) { const sqlEscaped = sqlString.escape(value); errors.push({ key, value, sanitizedValue: sqlEscaped, type: "SQL Injection", }); } return xssSanitized; }; const sanitizeObject = (obj: Record<string, any>): void => { for (const key in obj) { if (typeof obj[key] === "string") { obj[key] = sanitizeAndDetect(obj[key], key); } else if (typeof obj[key] === "object" && obj[key] !== null) { sanitizeObject(obj[key]); } } }; if (req.body) sanitizeObject(req.body); if (req.query) sanitizeObject(req.query as Record<string, any>); if (req.params) sanitizeObject(req.params as Record<string, any>); if (errors.length > 0) { return sendResponse(res, { success: false, message: "Potential security risks detected", statusCode: 400, details: errors.map((err) => ({ key: err.key, type: err.type, originalValue: err.value, sanitizedValue: err.sanitizedValue, })), }); } next(); };