From 241d2b3737871f376a198e968149a6bba1a6f31a Mon Sep 17 00:00:00 2001 From: Coracle-Bot Date: Tue, 15 Sep 2026 07:14:24 +0000 Subject: [PATCH] Derive the CSP script hashes from app.html --- svelte.config.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/svelte.config.js b/svelte.config.js index 5ffdc6b8..e658e1ee 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -1,5 +1,16 @@ import adapter from "@sveltejs/adapter-static" import {vitePreprocess} from "@sveltejs/vite-plugin-svelte" +import {createHash} from "node:crypto" +import {readFileSync} from "node:fs" + +// Sveltekit hashes the scripts it injects itself, but not the ones app.html carries, so those +// have to be named in script-src by hand. Hashing them here rather than pasting a literal is +// what stops an edit to app.html silently violating the policy. +const appHtmlScripts = [ + ...readFileSync(new URL("./src/app.html", import.meta.url), "utf8").matchAll( + /]*\bsrc=)[^>]*>([\s\S]*?)<\/script>/g, + ), +].map(([, script]) => "sha256-" + createHash("sha256").update(script).digest("base64")) /** @type {import('@sveltejs/kit').Config} */ export default { @@ -19,7 +30,7 @@ export default { }, csp: { directives: { - "script-src": ["self", "wasm-unsafe-eval", "https://plausible.coracle.social", "sha256-NpqGpeZTuPniNAucgyfqzWy9iIHwOswFzPzpigwvp/c="], + "script-src": ["self", "wasm-unsafe-eval", "https://plausible.coracle.social", ...appHtmlScripts], "worker-src": ["self", "blob:"], "style-src": ["self", "unsafe-inline"], "frame-src": ["none"],