19

In my extension I want to use my own WebAssembly module.

After loading my module (to background.html, or popup.html), I catch the compile error:

CompileError: WebAssembly.compile(): Wasm code generation disallowed by embedder.

Are wasm modules not supported in Chrome Extensions?

Xan
  • 74,770
  • 16
  • 179
  • 206
Joe Hill
  • 203
  • 1
  • 2
  • 4

4 Answers4

16

It seems from this issue that Chrome requires script-src: 'unsafe-eval' CSP directive be active for WebAssembly compilation. See this discussion as to why this is the case, at least for now.

Chrome Extensions come with default restrictions on CSP; that includes not allowing unsafe-eval. Some of the restrictions cannot be lifted; in this case, you can allow unsafe-eval by adding a manifest key:

"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"

This should be enough to test if Wasm works in extensions. But heed this warning from documentation:

However, we strongly recommend against doing this. These functions are notorious XSS attack vectors.

Instead of allowing unsafe-eval for your whole extension, you can sandbox code that requires it, using the following approach from the docs:

Using eval in Chrome Extensions. Safely.

The gist of it is to create a separate page in your extension, where unsafe-eval is allowed but Chrome API access is disallowed; you then embed this page in your extension and communicate with it using postMessage().

Xan
  • 74,770
  • 16
  • 179
  • 206
14

Chrome implemented special policy 'wasm-eval' exclusively for apps and extensions to resolve this problem. It is chrome-specific, but slowly moving into CSP and WebAssembly standards. Just replace 'unsafe-eval' with 'wasm-eval' in @Xan's solution.

Note though, this is still an attack vector and it's your responsibility to verify the source of executed assembly. See for example uBlock's author thoughts on this policy.

MadRunner
  • 605
  • 9
  • 17
2

I tried the 'unsafe-eval' and 'wasm-eval' provided by the other answers here but it didn't fix it. Turned out it's specific to the website. If I try it on Github, it doesn't work. But on reddit.com it works. Below is the error I'm seeing in Chrome developer mode. This is for Chrome extension made using Blazor NET6 with AOT. Hopefully someone finds this useful.

CompileError: WebAssembly.instantiate(): Wasm code generation disallowed by embedder
window.Module.s.printErr @ blazor.webassembly.js:1
(anonymous) @ blazor.webassembly.js:1
async function (async)
(anonymous) @ blazor.webassembly.js:1
window.Module.s.instantiateWasm @ blazor.webassembly.js:1
createWasm @ dotnet.6.0.0.cnc7cl383g.js:1
(anonymous) @ dotnet.6.0.0.cnc7cl383g.js:1
blazor.webassembly.js:1 Uncaught (in promise) CompileError: WebAssembly.instantiate(): Wasm code generation disallowed by embedder
    at blazor.webassembly.js:1
    at async blazor.webassembly.js:1
bob craig
  • 21
  • 2
1

I tried it in typo-script on a TYPO3-system and 'unsafe-eval' or 'wasm-eval' won't work. :-(

I defined it in the .htaccess and it works. :-)

<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin {linkToDomain}
Header set Access-Control-Allow-Credentials true
Header set Content-Security-Policy "default-src 'self' blob: 'unsafe-eval' 'wasm-eval'  {other code ...} ; {other code ...} script-src 'self' 'unsafe-eval' 'wasm-eval' {other code ...};   object-src 'self' 'wasm-eval';{other code ...}"
</IfModule>

P.S. Safari makes problems. After adding a site.manifest, extending the Content-Security-policy for default-src in TypoScript od TYPO3 and .htaccess it seems to work. (see above)

It seems to me, that every browser works different.

Padina
  • 11
  • 2