I've done my research and there are a few robust ways to sandbox user JS, namely:
- Use a JS VM that runs the JS using a sandboxed form of js, like VM.js
- Use a transpiler like Google Caja, which adds additional checks to preserve certain invariants and disallows specific codepaths
- Use a cross-domain (and/or
iframe, potentially with a WebWorker as well, e.g. Jailed
Unfortunately, none of these work well out of the box for my application. I'm trying to build a jsperf.com alternative (i.e. web-based JS benchmarking system), so the first two are out, since they would affect the performance of the user-supplied code, which completely invalidates any benchmarking results.
Jailed is closer, but also not a great alternative because A) its whitelist-only approach is so restrictive that my site would not be able to test the performance of a lot of features of the web (DOM operations, IndexedDb, WebWorkers, LocalStorage, etc.) without a lot of whitelisting that I'm not even sure would work and B) I'm not sure how well maintained (and thus secure) it is given how little activity there is on its GitHub repo.
What is the most permissive system (in terms of closeness to running unsandboxed) that I can safely use to execute user-supplied JS for benchmarking? Is a sandboxed
iframe sufficient so the benchmarks can at least access some DOM and other Web APIs? Is the WebWorker really necessary? What do jsfiddle and the like do?