diff options
| author | Fuwn <[email protected]> | 2026-06-01 13:09:56 +0000 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-06-01 13:09:56 +0000 |
| commit | 571e8b7961660aa193f755f8e4bb71e0984486da (patch) | |
| tree | a4819275b8cd8f8fb61bfac6310400eb3f081916 | |
| parent | fix(security): mark auth cookies Secure outside localhost (diff) | |
| download | due.moe-571e8b7961660aa193f755f8e4bb71e0984486da.tar.xz due.moe-571e8b7961660aa193f755f8e4bb71e0984486da.zip | |
feat(security): add Content-Security-Policy
No CSP existed, leaving the app without defense-in-depth against XSS.
Add a SvelteKit nonce-based policy (mode: auto): script-src limited to
self + per-request nonce + the analytics/Vercel script hosts, object-src
none, base-uri and frame-ancestors self. img/style/font/connect stay
permissive (https:) so the image proxy, CDNs, fonts and the many
cross-origin API calls keep working; the two inline app.html scripts
carry %sveltekit.nonce%. Verified in-browser across routes (no
violations, HMR and hydration intact) and via a production build.
| -rw-r--r-- | src/app.html | 4 | ||||
| -rw-r--r-- | svelte.config.js | 23 |
2 files changed, 25 insertions, 2 deletions
diff --git a/src/app.html b/src/app.html index a8eceb73..1f9fc4dd 100644 --- a/src/app.html +++ b/src/app.html @@ -94,7 +94,7 @@ <meta name="msapplication-square310x310logo" content="mstile-310x310.png" /> <!-- Umami is a simple, fast, and privacy-focused alternative to Google Analytics. --> - <script> + <script nonce="%sveltekit.nonce%"> if (!['localhost', '127.0.0.1'].includes(window.location.hostname)) { const script = document.createElement('script'); @@ -106,7 +106,7 @@ } </script> - <script> + <script nonce="%sveltekit.nonce%"> window.global = window; aoButa = ''; diff --git a/svelte.config.js b/svelte.config.js index 1f92f2c7..9ef30e18 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -13,6 +13,29 @@ const config = { $graphql: "./src/graphql", $houdini: "./$houdini", }, + csp: { + mode: "auto", + directives: { + "default-src": ["self"], + "script-src": [ + "self", + "https://analytics.fuwn.me", + "https://va.vercel-scripts.com", + ], + "style-src": ["self", "unsafe-inline", "https://proxy.due.moe"], + "font-src": [ + "self", + "data:", + "https://fonts.gstatic.com", + "https://proxy.due.moe", + ], + "img-src": ["self", "data:", "blob:", "https:"], + "connect-src": ["self", "https:", "ws:", "wss:"], + "object-src": ["none"], + "base-uri": ["self"], + "frame-ancestors": ["self"], + }, + }, }, split: true, }; |