← All issues

CSP wasm-unsafe-eval directive is not enforced during WebAssembly byte compilation

4003087

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.

+ if (!globalObject->webAssemblyEnabled())
+ return JSValue::encode(throwException(globalObject, throwScope,
+ createEvalError(globalObject, globalObject->webAssemblyDisabledErrorMessage())));

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.

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.

🔒

The new check placement across worker types and streaming redirect paths raises several edge cases worth security investigation.

Subscribe to read more