DEV Community

Aniket Saini
Aniket Saini

Posted on

Adding a Content Security Policy to a static SPA without breaking anything

Quietbench started from a scaffolded template that shipped with zero security headers. Adding them properly was less about writing the policy and more about not breaking the one tool that needs to stay permissive.

The easy part: X-Frame-Options: DENY, X-Content-Type-Options: nosniff, and a sane Referrer-Policy — free wins, nothing depends on being frameable.

The tricky part: the site has an API tester that needs to fetch() arbitrary user-supplied URLs. A locked-down connect-src 'self' would've quietly broken it. Fix was leaving connect-src * intentionally open while keeping everything else tight — script-src 'self', frame-ancestors 'none'. A CSP doesn't need to be uniformly strict, just strict where it matters for your app.

The gotcha: vite dev doesn't read the _headers file at all, so testing against the regular dev server tells you nothing about whether the CSP will actually apply. Cloudflare Pages reads _headers at deploy time — the only way to test that locally is running the build through wrangler pages dev dist, which mirrors production behavior. Skip that and you're shipping headers you never actually verified.

Also cleaned up @google/genai and express - leftover scaffold dependencies nothing imported. Not vulnerabilities, just unaudited surface for zero benefit. Dropped 121 packages.

Live at quietbench.dev if you want to check the headers yourself.

Top comments (1)

Collapse
 
frank_signorini profile image
Frank

This is super helpful! How do you handle `