diff --git a/next.config.js b/next.config.js index cb3c5604..6f494df9 100644 --- a/next.config.js +++ b/next.config.js @@ -10,4 +10,62 @@ module.exports = withMDX({ reactStrictMode: true, basePath: "/docs", pageExtensions: ["js", "jsx", "ts", "tsx", "md", "mdx"], + headers() { + return [ + { + source: '/(.*)', + headers: securityHeaders + } + ]; + }, }); + +const ContentSecurityPolicy = ` + default-src 'self'; + script-src 'self' 'unsafe-eval' 'unsafe-inline' *.youtube.com *.twitter.com; + child-src *.youtube.com *.google.com *.twitter.com; + style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; + font-src 'self' https://fonts.gstatic.com; + img-src * blob: data:; + media-src 'none'; + connect-src *; +`; + +const securityHeaders = [ + // https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP + { + key: 'Content-Security-Policy', + value: ContentSecurityPolicy.replaceAll(/\n/g, '') + }, + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy + { + key: 'Referrer-Policy', + value: 'origin-when-cross-origin' + }, + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options + { + key: 'X-Frame-Options', + value: 'DENY' + }, + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options + { + key: 'X-Content-Type-Options', + value: 'nosniff' + }, + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-DNS-Prefetch-Control + { + key: 'X-DNS-Prefetch-Control', + value: 'on' + }, + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security + { + key: 'Strict-Transport-Security', + value: 'max-age=31536000; preload' + }, + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy + // Opt-out of Google FLoC: https://amifloced.org/ + { + key: 'Permissions-Policy', + value: 'camera=(), microphone=(), geolocation=(), interest-cohort=()' + }, +];