diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts index 8d6ae9b..2b7d263 100644 --- a/backend/src/app.module.ts +++ b/backend/src/app.module.ts @@ -3,7 +3,9 @@ import { AppController } from './app.controller'; import { AppService } from './app.service'; import { ConfigModule } from '@nestjs/config'; import { DatabaseModule } from './modules/database-module/database.module'; -import { CspMiddleware } from './middleware/csp-middleware/csp-middleware'; +import { CspMiddleware } from './middleware/csp-middleware/csp.middleware'; +import { SecurityHeadersMiddleware } from './middleware/security-middleware/security.middleware'; +import { HttpsRedirectMiddleware } from './middleware/https-middlware/https-redirect.middleware'; @Module({ imports: [ @@ -18,7 +20,8 @@ import { CspMiddleware } from './middleware/csp-middleware/csp-middleware'; export class AppModule { configure(consumer: MiddlewareConsumer) { consumer - .apply(CspMiddleware) + // TODO: Redirect via Reverse Proxy all HTTP requests to HTTPS + .apply(CspMiddleware, SecurityHeadersMiddleware, HttpsRedirectMiddleware) .forRoutes({ path: '*', method: RequestMethod.ALL }); } } diff --git a/backend/src/middleware/csp-middleware/csp-middleware.ts b/backend/src/middleware/csp-middleware/csp.middleware.ts similarity index 94% rename from backend/src/middleware/csp-middleware/csp-middleware.ts rename to backend/src/middleware/csp-middleware/csp.middleware.ts index f9df509..b01790e 100644 --- a/backend/src/middleware/csp-middleware/csp-middleware.ts +++ b/backend/src/middleware/csp-middleware/csp.middleware.ts @@ -1,7 +1,6 @@ import { Injectable, NestMiddleware } from '@nestjs/common'; import { Request, Response, NextFunction } from 'express'; import { ConfigService } from '@nestjs/config'; -import { log } from 'console'; @Injectable() export class CspMiddleware implements NestMiddleware { diff --git a/backend/src/middleware/https-middlware/https-redirect.middleware.ts b/backend/src/middleware/https-middlware/https-redirect.middleware.ts new file mode 100644 index 0000000..59f0bb5 --- /dev/null +++ b/backend/src/middleware/https-middlware/https-redirect.middleware.ts @@ -0,0 +1,19 @@ +import { Injectable, NestMiddleware } from '@nestjs/common'; +import { ConfigService } from '@nestjs/config'; +import { NextFunction, Request, Response } from 'express'; + +@Injectable() +export class HttpsRedirectMiddleware implements NestMiddleware { + constructor(private configService: ConfigService) {} + + use(req: Request, res: Response, next: NextFunction) { + if (this.configService.get('NODE_ENV') === 'production') { + if (req.protocol === 'http') { + const httpsUrl = `https://${req.headers.host}${req.url}`; + res.redirect(httpsUrl); + } else { + next(); + } + } + } +} diff --git a/backend/src/middleware/security-middleware/security.middleware.ts b/backend/src/middleware/security-middleware/security.middleware.ts new file mode 100644 index 0000000..b766628 --- /dev/null +++ b/backend/src/middleware/security-middleware/security.middleware.ts @@ -0,0 +1,20 @@ +import { Injectable, NestMiddleware } from '@nestjs/common'; +import { Request, Response, NextFunction } from 'express'; +import { ConfigService } from '@nestjs/config'; + +@Injectable() +export class SecurityHeadersMiddleware implements NestMiddleware { + constructor(private configService: ConfigService) {} + + use(req: Request, res: Response, next: NextFunction): void { + if (this.configService.get('NODE_ENV') === 'production') { + res.setHeader( + 'Strict-Transport-Security', + 'max-age=63072000; includeSubDomains; preload' + ); + } + res.setHeader('X-Content-Type-Options', 'nosniff'); + res.setHeader('X-Frame-Options', 'SAMEORIGIN'); + next(); + } +}