diff --git a/apps/web/next.config.mjs b/apps/web/next.config.mjs new file mode 100644 index 000000000..206a5963b --- /dev/null +++ b/apps/web/next.config.mjs @@ -0,0 +1,31 @@ +const securityHeaders = [ + { + key: "X-Frame-Options", + value: "DENY" + }, + { + key: "X-Content-Type-Options", + value: "nosniff" + }, + { + key: "Referrer-Policy", + value: "strict-origin-when-cross-origin" + }, + { + key: "Permissions-Policy", + value: "camera=(), microphone=(), geolocation=()" + } +]; + +const nextConfig = { + async headers() { + return [ + { + source: "/:path*", + headers: securityHeaders + } + ]; + } +}; + +export default nextConfig; diff --git a/apps/web/package.json b/apps/web/package.json index cf96fe438..9b7189b56 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -6,6 +6,7 @@ "scripts": { "dev": "next dev", "test": "echo \"No web tests configured yet\"", + "test:security-headers": "node scripts/validate-security-headers.mjs", "lint": "next lint" }, "dependencies": { diff --git a/apps/web/scripts/validate-security-headers.mjs b/apps/web/scripts/validate-security-headers.mjs new file mode 100644 index 000000000..39c1f56bd --- /dev/null +++ b/apps/web/scripts/validate-security-headers.mjs @@ -0,0 +1,27 @@ +import assert from "node:assert/strict"; + +import nextConfig from "../next.config.mjs"; + +const requiredHeaders = new Map([ + ["X-Frame-Options", "DENY"], + ["X-Content-Type-Options", "nosniff"], + ["Referrer-Policy", "strict-origin-when-cross-origin"], + ["Permissions-Policy", "camera=(), microphone=(), geolocation=()"] +]); + +assert.equal(typeof nextConfig.headers, "function", "next.config.mjs must define headers()"); + +const routes = await nextConfig.headers(); +const allRoutes = routes.find((route) => route.source === "/:path*"); + +assert.ok(allRoutes, "security headers must apply to all routes"); + +const configuredHeaders = new Map( + allRoutes.headers.map((header) => [header.key, header.value]) +); + +for (const [key, value] of requiredHeaders) { + assert.equal(configuredHeaders.get(key), value, `${key} header is missing or incorrect`); +} + +console.log("Security headers configuration is valid."); diff --git a/contributors/agents.json b/contributors/agents.json index a3fbd7156..685ea7594 100644 --- a/contributors/agents.json +++ b/contributors/agents.json @@ -1,5 +1,12 @@ { - "agents": [], - "last_updated": "2026-06-03", - "total_contributions": 0 + "agents": [ + { + "name": "OpenAI Codex", + "model": "GPT-5", + "platform": "Codex", + "first_contribution": "2026-06-13" + } + ], + "last_updated": "2026-06-13", + "total_contributions": 1 }