Comment by simonw

20 hours ago

I want to build features - both client- and server-side - where users can provide JavaScript code that I then execute safely.

Just having a WebAssembly engine available isn't enough for this - something has to take that user-provided string of JavaScript and execute it within a safe sandbox.

Generally that means you need a JavaScript interpreter that has itself been compiled to WebAssembly. I've experimented with QuickJS itself for that in the past - demo here: https://tools.simonwillison.net/quickjs - but MicroQuickJS may be interesting as a smaller alternative.

If there's a better option than that I'd love to hear about it!

GraalVM supports running javascript in a sandbox with a bunch of convenient options for running untrusted code.

https://www.graalvm.org/latest/security-guide/sandboxing/

  • Oh that looks neat! It appears to have the memory limits I want (engine.MaxIsolateMemory) and a robust CPU limit: sandbox.MaxCPUTime

    One catch: the sandboxing feature isn't in the "community edition", so only available under the non-open-source (but still sometimes free, I think?) Oracle GraalVM.

This is generally the purpose of JavaScript execution environments like v8 or jsc (or quickjs although I understand not trusting that as a sandbox to the same degree). They are specifically intended for executing untrusted scripts (eg web browsers). Web assembly’s sandboxing comes from js sandboxing, since it was originally a feature of the same programs for the same reasons. Wrapping one sandbox in another is what I’m surprised by.

  • Running v8 itself as a sandbox is non-trivial, at least embedded in a Python or Node.js or similar application.

    The web is littered with libraries that half do that and then have a note in the README that says "do not rely on this as a secure sandbox".