From 8772a9b9e1263520d061b2d52058076adf9d495a Mon Sep 17 00:00:00 2001 From: Till JS Date: Wed, 8 Apr 2026 22:59:52 +0200 Subject: [PATCH] fix(csp): also allow jsdelivr in connect-src for transformers.js WASM preload The earlier fix added cdn.jsdelivr.net to script-src so the dynamic import() of onnxruntime-web's loader .mjs would resolve. But that's only half the story: transformers.js also issues plain fetch() calls to PRE-LOAD the .wasm binary and the .mjs factory before the backend selection code path is even reached. fetch() is governed by connect-src, not script-src, so the wasm preload was still blocked with "Failed to pre-load WASM binary: TypeError: Failed to fetch". The visible downstream symptom was identical to the previous bug ("no available backend found. ERR: [webgpu] TypeError: Failed to fetch dynamically imported module"), which made it look like the script-src fix hadn't taken effect. Add cdn.jsdelivr.net to the default connect-src too, alongside the existing script-src entry, with a comment explaining why both are required. Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/shared-utils/src/security-headers.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/shared-utils/src/security-headers.ts b/packages/shared-utils/src/security-headers.ts index ba4d8b9c7..b62af52cd 100644 --- a/packages/shared-utils/src/security-headers.ts +++ b/packages/shared-utils/src/security-headers.ts @@ -76,7 +76,12 @@ export function setSecurityHeaders(response: Response, options: SecurityHeadersO `script-src 'self' 'unsafe-inline' 'wasm-unsafe-eval' https://stats.mana.how https://glitchtip.mana.how https://cdn.jsdelivr.net ${scriptSrc.join(' ')}`.trim(), "style-src 'self' 'unsafe-inline'", `img-src 'self' data: blob: https: ${imgSrc.join(' ')}`.trim(), - `connect-src 'self' https://stats.mana.how https://glitchtip.mana.how ${connectSrc.join(' ')}`.trim(), + // jsDelivr also has to be in connect-src because @huggingface/transformers + // pre-loads the WASM binary and the loader .mjs via plain fetch() (not + // just dynamic import) when selecting the ONNX backend. The script-src + // allowlist alone covers the import() but not the fetch() — both are + // required for the WebGPU backend resolver to succeed. + `connect-src 'self' https://stats.mana.how https://glitchtip.mana.how https://cdn.jsdelivr.net ${connectSrc.join(' ')}`.trim(), `font-src 'self' ${fontSrc.join(' ')}`.trim(), mediaSrc.length > 0 ? `media-src 'self' ${mediaSrc.join(' ')}`.trim() : '', "object-src 'none'",