HTTP Security Headers Hardening
# 🔒 HTTP Security Headers Hardening
## Context
OpenScrut currently does not set any security-related HTTP response headers. Modern web applications should include headers that mitigate common attack vectors (clickjacking, MIME-type sniffing, XSS, data leaks via `Referer`, etc.). Adding these headers is a low-effort, high-impact security improvement.
Related: OWASP Secure Headers Project — https://owasp.org/www-project-secure-headers/
## Requirements
- Add a Next.js middleware (`src/middleware.ts`) or use `next.config.ts` `headers()` to inject security headers on every response.
- Headers to set:
- `Strict-Transport-Security: max-age=63072000; includeSubDomains; preload` (HSTS — HTTPS enforcement)
- `X-Content-Type-Options: nosniff` (prevent MIME-type sniffing)
- `X-Frame-Options: DENY` (clickjacking protection, complement to CSP `frame-ancestors`)
- `Referrer-Policy: strict-origin-when-cross-origin` (limit referrer leakage)
- `Permissions-Policy: camera=(), microphone=(), geolocation=()` (disable unused browser features)
- `Content-Security-Policy` — start with a restrictive policy and loosen only as needed. At minimum: `default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'`
- `X-DNS-Prefetch-Control: off`
- `X-Permitted-Cross-Domain-Policies: none`
- CSP must be compatible with the existing Service Worker (`sw.ts`) and any inline styles used by shadcn/ui or Tailwind.
- HSTS must only be sent when the app is served over HTTPS (respect `NODE_ENV` or a dedicated env var).
- Headers must not break the PWA manifest or offline fallback.
## Privacy
No additional personal data collected. `Referrer-Policy` actually *reduces* data leakage.
## Acceptance Criteria
- [ ] Security headers are present on all responses (verified via `curl -I` and browser DevTools).
- [ ] CSP does not break any existing page (dashboard, admin, assessor views, offline fallback).
- [ ] HSTS is only sent over HTTPS / in production.
- [ ] Integration test in `tests/api/` asserts expected headers on a sample route.
- [ ] E2E smoke test confirms the app still works end-to-end with headers active.
- [ ] Verified in both light and dark mode.
- [ ] Documentation updated if any env var is added (e.g., `CSP_REPORT_URI`).
issue