Problem
The app sets no security headers on any response. next.config.ts defines no headers() block, vercel.json contains only a buildCommand, and proxy.ts sets x-current-path on the request headers only — nothing writes response headers.
Missing across every route:
| Header |
Consequence of absence |
Content-Security-Policy |
No defense-in-depth under the XSS surface. The surface is clean today (no dangerouslySetInnerHTML, no any), but nothing constrains a future regression. |
Strict-Transport-Security |
No HSTS; first-request downgrade remains possible. |
X-Frame-Options / CSP frame-ancestors |
/applications, /applications/[id], /users, /global-questions and /positions/[id]/edit are all framable — clickjacking against admin and reviewer controls (status changes, bulk updates, admin promotion, question deletion). |
X-Content-Type-Options: nosniff |
Relevant because downloadQuestionFileAnswer serves applicant-uploaded PDF/PNG/JPG bytes back to reviewers. |
Referrer-Policy |
Full paths including /applications/[id] leak to third-party origins via outbound links. |
The app is authenticated, stores applicant PII, and is publicly launched as of 2026-08-16.
Acceptance criteria
Notes
- Split the work by risk. The four non-CSP headers are inert and can ship immediately. CSP is the one that can break things:
next-themes injects an inline script (needs a nonce or hash) and Neon Auth redirects to an external origin. Suggest landing CSP as Content-Security-Policy-Report-Only first and promoting it once clean.
next.config.ts is the right home, not proxy.ts. The proxy matcher deliberately excludes static assets, /429, and prefetch requests, so headers set there would be applied inconsistently.
- No schema change, no migration, no new dependency.
Found in the 2026-08-16 pre-launch review of main @ 7299ffb. Not part of the 2026-08-10 full platform audit backlog (#401), which scoped permissions, business logic, design, links, DRY, history, workflows and build/CI — but not runtime hardening.
Problem
The app sets no security headers on any response.
next.config.tsdefines noheaders()block,vercel.jsoncontains only abuildCommand, andproxy.tssetsx-current-pathon the request headers only — nothing writes response headers.Missing across every route:
Content-Security-PolicydangerouslySetInnerHTML, noany), but nothing constrains a future regression.Strict-Transport-SecurityX-Frame-Options/ CSPframe-ancestors/applications,/applications/[id],/users,/global-questionsand/positions/[id]/editare all framable — clickjacking against admin and reviewer controls (status changes, bulk updates, admin promotion, question deletion).X-Content-Type-Options: nosniffdownloadQuestionFileAnswerserves applicant-uploaded PDF/PNG/JPG bytes back to reviewers.Referrer-Policy/applications/[id]leak to third-party origins via outbound links.The app is authenticated, stores applicant PII, and is publicly launched as of 2026-08-16.
Acceptance criteria
headers()block innext.config.tsapplying to all routesStrict-Transport-Security,X-Content-Type-Options: nosniff,Referrer-Policy, and a frame-ancestors denial are setnext-themesinline scriptNotes
next-themesinjects an inline script (needs a nonce or hash) and Neon Auth redirects to an external origin. Suggest landing CSP asContent-Security-Policy-Report-Onlyfirst and promoting it once clean.next.config.tsis the right home, notproxy.ts. The proxy matcher deliberately excludes static assets,/429, and prefetch requests, so headers set there would be applied inconsistently.Found in the 2026-08-16 pre-launch review of
main@7299ffb. Not part of the 2026-08-10 full platform audit backlog (#401), which scoped permissions, business logic, design, links, DRY, history, workflows and build/CI — but not runtime hardening.