@@ -2,10 +2,59 @@ import type { NextConfig } from "next";
22
33const isDev = process . env . NODE_ENV !== "production" ;
44
5+ /**
6+ * Content Security Policy header.
7+ * All API calls (OIDC, backend API) happen server-side,
8+ * so browser CSP only needs 'self'.
9+ */
10+ const cspHeader = `
11+ default-src 'self';
12+ script-src 'self' 'unsafe-inline';
13+ style-src 'self' 'unsafe-inline';
14+ img-src 'self' blob: data:;
15+ font-src 'self';
16+ connect-src 'self';
17+ form-action 'self';
18+ frame-ancestors 'none';
19+ base-uri 'self';
20+ object-src 'none';
21+ upgrade-insecure-requests;
22+ `
23+ . replace ( / \s { 2 , } / g, " " )
24+ . trim ( ) ;
25+
526const nextConfig : NextConfig = {
6- /* config options here */
727 reactCompiler : true ,
828 output : "standalone" ,
29+ async headers ( ) {
30+ return [
31+ {
32+ source : "/(.*)" ,
33+ headers : [
34+ {
35+ key : "Content-Security-Policy" ,
36+ value : cspHeader ,
37+ } ,
38+ {
39+ key : "X-Content-Type-Options" ,
40+ value : "nosniff" ,
41+ } ,
42+ {
43+ key : "X-Frame-Options" ,
44+ value : "DENY" ,
45+ } ,
46+ {
47+ key : "Referrer-Policy" ,
48+ value : "strict-origin-when-cross-origin" ,
49+ } ,
50+ {
51+ key : "Permissions-Policy" ,
52+ value : "camera=(), microphone=(), geolocation=()" ,
53+ } ,
54+ ] ,
55+ } ,
56+ ] ;
57+ } ,
958 async rewrites ( ) {
1059 if ( ! isDev ) return [ ] ;
1160
0 commit comments