Stream: general

Topic: CSP directive wasm-src would break the idiom


view this post on Zulip Stijn van Drongelen (Aug 04 2026 at 17:35):

Hi all! I'm not sure where to discuss this properly, so please don't hesitate to direct me elsewhere if needed.

There is an open issue on the Content-Security-Policy repository about a more fine-grained directive for Wasm. The only way to enable WebAssembly on CSP-enabled web pages is to specify script-src 'wasm-unsafe-eval'. There is no way to be more specific, and auditors hate to see the word unsafe in a security header, so we need something better.

In a perfect world, developers and (more likely) system administrators just have to add some CSP headers to webserver configurations, without changing the typical WebAssembly.instantiateStreaming(fetch(...), ...) idiom. But after some digging, I've come to the tenative conclusion that that's not going to work.

By design (reiterated here), fetch() will always have connect-src as the effective directive. CSP picks the effective directive based on the initiator and the destination of the request. If the browser tries to download a picture to embed it on the page, the destination is "image", and CSP determines the effective directive is img-src. Using the fetch() function always causes a request with destination "", because the underlying Request constructor doesn't specify otherwise.

A fused form (WebAssembly.fetchAndInstantiate(...)) would probably be horrible. Both functions have reasons to want multiple arguments, which gets messy when mixing them together into one function. Annoying for developers, outright bad for the sysadmins who'd have to manually rewrite something to make the CSP work.

So far, I've landed on WebAssembly.instantiateStreaming(WebAssembly.fetch(...), ...), where WebAssembly.fetch() does everything the global fetch() does, except also setting an appropriate destination for Wasm. I expect that such a proposal would only succeed if WebAssembly.fetch() somehow also ensures that the response can only be used by WebAssembly.instantiateStreaming and friends, and that WebAssembly.instantiateStreaming only accepts responses that originate from WebAssembly.fetch() (unless 'wasm-unsafe-eval' was specified). It may have to be even more thorough, because I find it difficult to imagine whether there's a risk of exfiltration if the promise (not just the promised response) can be used outside of that context.

I'd love to have wasm-src, but I'm not sure if others would tolerate WebAssembly.fetch(). What are your thoughts?

view this post on Zulip Milan (rajsite) (Aug 04 2026 at 18:01):

My understanding is WebAssembly source phase imports can help with this kind of issue. Eliminates the need for explicit fetch and rely on module resolution. See the WebAssembly section of the explainer: https://github.com/tc39/proposal-source-phase-imports#wasm-module-source

And the Security CSP note: https://github.com/tc39/proposal-source-phase-imports#security-benefits


Last updated: Aug 30 2026 at 09:07 UTC