@@ -32,14 +32,18 @@ app.use(requestIdMiddleware);
3232app . disable ( 'x-powered-by' ) ;
3333
3434// Helmet-equivalent core headers without external dependency.
35+ // Strict CSP applied globally; the /api-docs route overrides it below for Swagger UI.
3536app . use ( ( req : Request , res : Response , next : NextFunction ) => {
3637 res . setHeader ( 'X-Content-Type-Options' , 'nosniff' ) ;
3738 res . setHeader ( 'X-Frame-Options' , 'DENY' ) ;
3839 res . setHeader ( 'Referrer-Policy' , 'no-referrer' ) ;
3940 res . setHeader ( 'X-DNS-Prefetch-Control' , 'off' ) ;
4041 res . setHeader ( 'X-Download-Options' , 'noopen' ) ;
4142 res . setHeader ( 'X-Permitted-Cross-Domain-Policies' , 'none' ) ;
42- if ( isProduction ) {
43+ res . setHeader ( 'Content-Security-Policy' , "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; frame-ancestors 'none'; object-src 'none'" ) ;
44+ res . setHeader ( 'Cross-Origin-Opener-Policy' , 'same-origin' ) ;
45+ res . setHeader ( 'Cross-Origin-Resource-Policy' , 'same-origin' ) ;
46+ if ( process . env . NODE_ENV === 'production' ) {
4347 res . setHeader ( 'Strict-Transport-Security' , 'max-age=31536000; includeSubDomains' ) ;
4448 }
4549 next ( ) ;
@@ -78,7 +82,11 @@ app.use(express.json());
7882app . use ( sandboxMiddleware ) ;
7983
8084// Swagger UI setup
81- app . use ( '/api-docs' , swaggerUi . serve , swaggerUi . setup ( swaggerSpec , {
85+ // Override CSP for /api-docs only: Swagger UI requires inline scripts/styles.
86+ app . use ( '/api-docs' , ( req : Request , res : Response , next : NextFunction ) => {
87+ res . setHeader ( 'Content-Security-Policy' , "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-ancestors 'none'; object-src 'none'" ) ;
88+ next ( ) ;
89+ } , swaggerUi . serve , swaggerUi . setup ( swaggerSpec , {
8290 customCss : '.swagger-ui .topbar { display: none }' ,
8391 customSiteTitle : 'FlowFi API Documentation' ,
8492} ) ) ;
0 commit comments