import { Injectable, NestInterceptor, ExecutionContext, CallHandler, } from "@nestjs/common"; import { Observable } from "rxjs"; /** * Strips HTML/script tags from all string values in the request body. * Applied globally to prevent stored XSS via API inputs. */ @Injectable() export class SanitizeInterceptor implements NestInterceptor { intercept(context: ExecutionContext, next: CallHandler): Observable { const request = context.switchToHttp().getRequest(); if (request.body && typeof request.body === "object") { request.body = this.sanitize(request.body); } return next.handle(); } private sanitize(value: unknown): unknown { if (typeof value === "string") { return this.stripTags(value); } if (Array.isArray(value)) { return value.map((item) => this.sanitize(item)); } if (value !== null && typeof value === "object") { const sanitized: Record = {}; for (const [key, val] of Object.entries(value)) { sanitized[key] = this.sanitize(val); } return sanitized; } return value; } private stripTags(input: string): string { return input.replace(/<[^>]*>/g, ""); } }