From e7e2c47f2ae94d673626b032ddcee30a088e1d73 Mon Sep 17 00:00:00 2001 From: Ho Ngoc Hai Date: Wed, 8 Apr 2026 13:24:50 +0700 Subject: [PATCH] fix(security): register SanitizeInput and CSRF middleware in app.module.ts - Register SanitizeInputMiddleware for all routes to prevent stored XSS - Register CsrfMiddleware for all routes (sets cookie on GET, validates on state-changing methods) - Remove unsafe-inline from CSP scriptSrc directive - AppModule now implements NestModule with configure() method Co-Authored-By: Paperclip --- apps/api/src/app.module.ts | 18 ++++++++++++++++-- apps/api/src/main.ts | 2 +- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/apps/api/src/app.module.ts b/apps/api/src/app.module.ts index 5c7af48..0c01a69 100644 --- a/apps/api/src/app.module.ts +++ b/apps/api/src/app.module.ts @@ -1,4 +1,4 @@ -import { Module } from '@nestjs/common'; +import { type MiddlewareConsumer, Module, type NestModule } from '@nestjs/common'; import { APP_GUARD } from '@nestjs/core'; import { CqrsModule } from '@nestjs/cqrs'; import { ThrottlerModule } from '@nestjs/throttler'; @@ -13,6 +13,8 @@ import { PaymentsModule } from '@modules/payments'; import { SearchModule } from '@modules/search'; import { SharedModule } from '@modules/shared'; import { ThrottlerBehindProxyGuard } from '@modules/shared/infrastructure/guards/throttler-behind-proxy.guard'; +import { CsrfMiddleware } from '@modules/shared/infrastructure/middleware/csrf.middleware'; +import { SanitizeInputMiddleware } from '@modules/shared/infrastructure/middleware/sanitize-input.middleware'; import { SubscriptionsModule } from '@modules/subscriptions'; import { AppController } from './app.controller'; @@ -62,4 +64,16 @@ import { AppController } from './app.controller'; }, ], }) -export class AppModule {} +export class AppModule implements NestModule { + configure(consumer: MiddlewareConsumer): void { + // Sanitize all incoming request strings to prevent stored XSS + consumer + .apply(SanitizeInputMiddleware) + .forRoutes('*'); + + // CSRF double-submit cookie (sets on GET, validates on state-changing methods) + consumer + .apply(CsrfMiddleware) + .forRoutes('*'); + } +} diff --git a/apps/api/src/main.ts b/apps/api/src/main.ts index da17775..f50d59b 100644 --- a/apps/api/src/main.ts +++ b/apps/api/src/main.ts @@ -45,7 +45,7 @@ async function bootstrap() { contentSecurityPolicy: { directives: { defaultSrc: ["'self'"], - scriptSrc: ["'self'", "'unsafe-inline'"], + scriptSrc: ["'self'"], styleSrc: ["'self'", "'unsafe-inline'"], imgSrc: ["'self'", 'data:', 'https:', 'blob:'], connectSrc: ["'self'"],