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" },