8n8
8n8

Reputation: 1382

Can I use WebAssembly to safely execute untrusted user code within my web app?

In a web app I am building, I have a need to execute untrusted user code within the app (in the browser). The untrusted code is given a string from Javascript, and should do its stuff and produce a new string. So I want to make sure it can't do any IO, like modifying the DOM, making HTTP requests, or accessing the local cache. To be clear, one user would upload some untrusted code, which would be executed in other users' browsers.

I clearly don't want to run some Javascript using eval, since that could do anything. My idea is that a user could upload some WebAssembly, created with Emscripten and C or Rust or whatever. The Javascript would initialise a memory buffer containing the input string, and the WebAssembly would read this and then write its output back to the buffer, which could then be used in JS.

This is what the Webassembly spec says:

WebAssembly provides no ambient access to the computing environment in which code is executed. Any interaction with the environment, such as I/O, access to resources, or operating system calls, can only be performed by invoking functions provided by the embedder and imported into a WebAssembly module. An embedder can establish security policies suitable for a respective environment by controlling or limiting which functional capabilities it makes available for import. Such considerations are an embedder’s responsibility and the subject of API definitions for a specific environment.

My understanding is that WebAssembly is guaranteeing that it can only do dangerous things if I explicitly pass them in when initializing the module, which of course I wouldn't do.

So my question is: is there any way someone could make some WASM code that could do some IO under these circumstances? Or any other nasty things?

Upvotes: 13

Views: 2276

Answers (2)

ColinE
ColinE

Reputation: 70142

Yes, you could compile a JavaScript virtual machine to WebAssembly for the purposes of executing untrusted user code. WebAssembly has no built in I/O, therefore you can run code in such a way that it can do no harm at all. For practical purposes you’d want to provide a secure API which this code could use in order to perform any useful functions. In your case this sounds very simple - your API simply allows a string to be exchanged.

However, there are some simpler alternatives - see this excellent blog post from Figma that discusses that specifically:

https://www.figma.com/blog/how-we-built-the-figma-plugin-system/

It also discusses various other useful options such as Realms.

Upvotes: 7

anthumchris
anthumchris

Reputation: 9090

The WASM security model is very strong and wouldn't have IO access unless you explicitly declare it. WASM is not a JS runtime engine, so it won't execute JS. WASM does not have DOM access, so you're safe there. Hopefully others can chime in who could offer more detailed explications.

Upvotes: 4

Related Questions