diff --git a/next.config.ts b/next.config.ts index 0bd2f11..ebb7380 100755 --- a/next.config.ts +++ b/next.config.ts @@ -2,11 +2,59 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { output: "standalone", - /* config options here */ typescript: { ignoreBuildErrors: true, }, reactStrictMode: false, + // PRD §5.6: CSP, nosniff, no-store on private files, HSTS at the proxy + async headers() { + return [ + { + source: "/(.*)", + headers: [ + // Content-Security-Policy (PRD §5.6) + { + key: "Content-Security-Policy", + value: [ + "default-src 'self'", + "script-src 'self' 'unsafe-inline' 'unsafe-eval'", + "style-src 'self' 'unsafe-inline'", + "img-src 'self' data: https:", + "font-src 'self'", + "connect-src 'self'", + "frame-ancestors 'none'", + "form-action 'self'", + "base-uri 'self'", + ].join("; "), + }, + // X-Content-Type-Options (PRD §5.6: nosniff) + { key: "X-Content-Type-Options", value: "nosniff" }, + // X-Frame-Options (prevent clickjacking) + { key: "X-Frame-Options", value: "DENY" }, + // Referrer-Policy + { key: "Referrer-Policy", value: "strict-origin-when-cross-origin" }, + // Permissions-Policy (disable camera, microphone, geolocation) + { + key: "Permissions-Policy", + value: "camera=(), microphone=(), geolocation=(), payment=()", + }, + // Strict-Transport-Security (HSTS — PRD says at the proxy, but we also set it here) + { + key: "Strict-Transport-Security", + value: "max-age=63072000; includeSubDomains; preload", + }, + ], + }, + { + // Private files: no-store (PRD §5.6: "no-store on private files") + source: "/api/(.*)", + headers: [ + { key: "Cache-Control", value: "no-store, no-cache, must-revalidate" }, + { key: "Pragma", value: "no-cache" }, + ], + }, + ]; + }, }; export default nextConfig;