Files
Mangalord/frontend/csp-config.js
MechaCat02 5784483a57 fix: add CSP and defense-in-depth security response headers
Document responses carried no CSP, X-Frame-Options, Referrer-Policy, or
Permissions-Policy — leaving clickjacking and zero script-injection defense
in depth (security audit T4).

- svelte.config.js: enable kit.csp hash mode. SvelteKit hashes its own inline
  hydration scripts; the inline theme <script> in app.html isn't part of
  %sveltekit.head%, so its sha256 is pinned by hand (csp-config.js) and added
  to script-src alongside object-src 'none', base-uri 'self', frame-ancestors
  'none'. Styles stay unconstrained (Svelte emits dynamic inline style= attrs).
- hooks.server.ts: applySecurityHeaders() sets X-Frame-Options: DENY,
  Referrer-Policy: strict-origin-when-cross-origin, X-Content-Type-Options:
  nosniff, and a Permissions-Policy locking down unused features, only when the
  response hasn't already set them.
- src/csp-theme-hash.test.ts: drift guard against editing the theme script
  without updating THEME_SCRIPT_HASH.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 19:27:27 +02:00

11 lines
610 B
JavaScript

// Shared CSP constants, kept dependency-free so both svelte.config.js (loaded by
// Node when Vite starts) and the vitest drift-guard test (jsdom env) can import
// it without pulling in adapter-node / esbuild.
// sha256 of the inline theme <script> in src/app.html, base64-encoded, wrapped
// for the CSP `script-src` allowlist. SvelteKit's kit.csp hash mode does not
// cover app.html template scripts, so this is pinned by hand. src/csp-theme-hash.test.ts
// recomputes it from app.html and fails if it drifts.
export const THEME_SCRIPT_HASH =
"'sha256-qj6Oim9siqow/Su+v47sZHJeJci+M/RQwGXn53eSULQ='";