From 6b10f0b90242747ed279e174b8336fdb08ac990a Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Tue, 4 Aug 2026 09:55:49 -0400 Subject: [PATCH] Fix live login: allow WASM compilation under the deployment CSP script-src 'self' alone forbids WebAssembly.compile, and Argon2id (hash-wasm) compiles a WASM module in the crypto worker -- so the CSP added in the second-audit hardening broke every password flow on the deployed site. Add 'wasm-unsafe-eval', which permits WASM compilation only; JS eval stays banned, and the policy test now pins both facts so neither can regress silently. Co-Authored-By: Claude Fable 5 --- packages/widget/src/securityPolicy.test.ts | 10 ++++++++++ vercel.json | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/widget/src/securityPolicy.test.ts b/packages/widget/src/securityPolicy.test.ts index 0ffc04c..20dc62c 100644 --- a/packages/widget/src/securityPolicy.test.ts +++ b/packages/widget/src/securityPolicy.test.ts @@ -79,6 +79,16 @@ describe("widget security policy", () => { expect(headers.get("Content-Security-Policy")).toContain( "frame-ancestors 'none'", ); + // Argon2id (hash-wasm) compiles a WASM module inside the crypto worker; + // script-src without 'wasm-unsafe-eval' blocks WebAssembly.compile and + // breaks every password flow on the deployed site. The keyword permits + // WASM compilation ONLY -- plain 'unsafe-eval' (JS eval) must stay out. + expect(headers.get("Content-Security-Policy")).toContain( + "script-src 'self' 'wasm-unsafe-eval'", + ); + expect(headers.get("Content-Security-Policy")).not.toContain( + " 'unsafe-eval'", + ); for (const required of [ "X-Content-Type-Options", "Referrer-Policy", diff --git a/vercel.json b/vercel.json index 2f2eff1..d155f7f 100644 --- a/vercel.json +++ b/vercel.json @@ -7,7 +7,7 @@ "headers": [ { "key": "Content-Security-Policy", - "value": "default-src 'none'; script-src 'self'; worker-src 'self'; connect-src 'self' wss:; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self'; manifest-src 'self'; base-uri 'none'; form-action 'self'; frame-ancestors 'none'; object-src 'none'; upgrade-insecure-requests" + "value": "default-src 'none'; script-src 'self' 'wasm-unsafe-eval'; worker-src 'self'; connect-src 'self' wss:; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self'; manifest-src 'self'; base-uri 'none'; form-action 'self'; frame-ancestors 'none'; object-src 'none'; upgrade-insecure-requests" }, { "key": "X-Content-Type-Options", "value": "nosniff" }, { "key": "Referrer-Policy", "value": "no-referrer" },