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'"],