Ask HN: How to safely execute user code in browser (like observablehq)?

6 points by tjchear ↗ HN
The environment within which the code could execute could belong to other users, how can we do this safely? My initial high level thought is 1) custom domain, 2) iframe security policies, 3) setting some https headers? 4) execute in web worker 5) message passing back to host to modify UI, but I don't know the details, and I may have missed other things.

9 comments

[ 2.7 ms ] story [ 28.5 ms ] thread
You don't, and it would be irresponsible. Run it on your server and deliver known-safe results back to the client. Besides, client PCs aren't there to do your bidding--don't offload your responsibilities onto them. You're just asking for a (very inefficient) bitcoin farm.
Good point. Does Observablehq do something similar then?
You need a sandbox but I don't think web-browser sandboxes are designed for your use case, when the web application doesn't trust its own code.

Considering the constraints I would experiment with a virtual machine. It can use your own set of instructions, like high level domain specific instructions in a json, or something lower level like a simple assembly.

You could use qemu in WebAssembly in a webworker and hope for no vm escape hack. Or a lua interpreter implemented in javascript.

I guess I should have rephrased my question then. How would I go about doing something similar to what observablehq is doing as far as executing user code on the fly goes, short of writing a js interpreter in js?
This might be an unpopular opinion, but browser extensions already allow user code to be executed in browser. Your thoughts seem to be along the same lines. You should look at how chrome extensions are executed and follow the same.
Yep: custom domain, iframe security policies. Communicate with the iframe via postMessage only, be strict about message origins, and have limited trust in those messages, too. Strict CSP policies and use the 'sandbox' iframe attribute.

iframes are cruddy, but they are designed for this - the long era of iframe-based embedded advertisements caused vendors to double-down on those security policies.

Observable doesn't use WebWorkers, duktape, or a custom JavaScript interpreter. If you had sandboxed JavaScript that didn't need access to the DOM, those might be options, but if you want people to write JavaScript like usually, they don't do any good.

This would cover protecting user code from the app code but what can you do to protect code from one user against code from another user? Custom domain for every user?
Yes, use per-user domains to make sure that things like localStorage, which is domain-associated, is not leaked from one script to another.