CSP wasm-unsafe-eval directive is not enforced during WebAssembly byte compilation
CSP's wasm-unsafe-eval gates whether a browsing context may compile and execute WebAssembly. WebKit implemented the gate through globalObject->webAssemblyEnabled() — but the call appeared only in JSWebAssemblyInstance::tryCreate() (instantiation), not at the compilation stage. A WebAssembly.Module is structured-cloneable per spec, so an attacker could compile in a context that bypasses the check, postMessage the Module to a same-origin Worker, and instantiate there — defeating the policy entirely.
The check is added to WebAssembly.compile(), new WebAssembly.Module(), WebAssembly.compileStreaming(), and WebAssembly.instantiateStreaming(). Each rejects with CompileError before bytecode parsing or network fetch begins. Two long-open FIXMEs (bugs 173977 and 173105) are removed.
Significance
Closes a real CSP bypass that had been latent since the streaming APIs were introduced — wasm-unsafe-eval now blocks Module construction itself, not just instantiation.
Audit directions
globalObject->webAssemblyEnabled() is checked against the calling global object — verify every Worker global (Dedicated, Shared, Service, Worklet) has consistent CSP context independently enforced, and none inherit a permissive parent. Streaming variants check CSP before fetch starts; a fetch response delivered via redirect carries its own headers — confirm whether a redirect can shift compile into a different CSP context than originally checked. WebAssembly.validate() remains unchecked by design; if a future code path uses validate() results to short-circuit compilation, that boundary is worth probing. Audit whether other entry points (e.g., WebAssembly.instantiate() with a BufferSource) received equivalent guards.