From cc6ebee6f551cc521dcf2e5341e349f579669fd2 Mon Sep 17 00:00:00 2001 From: Till JS Date: Wed, 8 Apr 2026 23:06:33 +0200 Subject: [PATCH] fix(csp): allow blob: in script-src so onnxruntime-web Worker can spawn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After jsDelivr was allowlisted, transformers.js progressed one step further: it successfully fetched the ort-wasm-simd-threaded.asyncify.mjs loader, then tried to wrap it in a `URL.createObjectURL(new Blob([...]))` and instantiate the result as a multi-threaded Web Worker. The blob: URL scheme is treated as its own CSP source by browsers, so the existing script-src — which only allows 'self', specific HTTPS hosts, and 'wasm-unsafe-eval' — blocked it. Add `blob:` to the mana-web scriptSrc list. The blob: scheme always inherits the document origin (you can't `URL.createObjectURL` a Blob from another origin), so this allowlists nothing more than our own runtime-generated worker scripts. It does NOT loosen the protection against remote-script injection. Worth knowing for future debugging: when transformers.js or any WebGPU/onnxruntime-web stack hits "Failed to fetch dynamically imported module: blob:..." after a successful dynamic import from a CDN, the next CSP layer is always blob: in script-src. Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/mana/apps/web/src/hooks.server.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/mana/apps/web/src/hooks.server.ts b/apps/mana/apps/web/src/hooks.server.ts index c15809951..33ff1a939 100644 --- a/apps/mana/apps/web/src/hooks.server.ts +++ b/apps/mana/apps/web/src/hooks.server.ts @@ -107,7 +107,14 @@ window.__PUBLIC_GLITCHTIP_DSN__ = ${JSON.stringify(PUBLIC_GLITCHTIP_DSN)}; // onnxruntime-web WASM loader from jsDelivr at backend selection // time via a dynamic import(). Browsers route dynamic imports // through script-src. - scriptSrc: ['https://cdn.jsdelivr.net'], + // + // `blob:` is also required because once the loader .mjs is fetched, + // onnxruntime-web wraps it in `URL.createObjectURL(new Blob([...]))` + // and instantiates the result as a multi-threaded Web Worker. The + // blob URL scheme is its own CSP source — we only allow it for + // our own origin (the implicit base of blob: is the document + // origin), so this can't be used to load remote scripts. + scriptSrc: ['https://cdn.jsdelivr.net', 'blob:'], connectSrc: [ PUBLIC_MANA_AUTH_URL_CLIENT, PUBLIC_SYNC_SERVER_URL_CLIENT,