How to sandbox untrusted JavaScript code execution
This could be useful if you want to have a in-browser repl or interactive playground of some sort.
Update with Solution:
The easiest/best approach I found was creating an <iframe>
with the srcDoc
attribute set (which sets the src of the iframe to an inline string).
Then you postMessage
code you want to Function('return eval(code)')()
to that iframe. Works
very well! This creates a new function and then runs it. Downside is that you
have to explicitly return. Upside over eval is that it wipes the old state so
variables don't stick around between cycles.
We fix those issues by using eval and wrapping that in a Function(eval)()
.
This allows state to be reset between cycles (due to new function being defined
and run) AND it also auto-returns the last expression (due to it being eval
).
Very nice!
Only caveat: window.varName
will persist between cycles. We should disallow
that somehow... We could periodically reset the srcDoc...? This could turn into
a mem leak... As long as we remove the message
eventListener in the iframe first?
Another solution is to use proxy to disable any window modification... hm... interesting...
Proxy doesn't work, but other similar solutions might... https://stackoverflow.com/questions/38759116/how-can-i-detect-when-a-global-variable-is-set-in-javascript
This could work! https://stackoverflow.com/questions/45437583/proxy-on-window#:~:text=4%20Answers&text=Short%20answer%20is%20no.,need%20to%20do%20such%20shenanigans.
Wrapping the code to execute in a proxy like ^ would definietly allow for some interesting eval features... validation/ santizing etc...
It currently works similarly to the console repl. Which is pretty acceptable.
Maybe future mitigation could be linting / checking for window.*
setting and
we could warn / block against that (just don't run the eval). Or we could use
ast or regex to change / filter that out.
We could also have a "reset" button that actually replaces the iframe and resets state completely.
Prior notes
Most promising approaching atm: Q: how secure is secure enough?
- iframe 2.5 SW
- WASM
- node websockets
- closure lib
Reading: Eval vs new Function() https://stackoverflow.com/questions/4599857/are-eval-and-new-function-the-same-thing
Notes: klipse is great, but pollutes the global scope. So separate runs aren't accurate.
Reading: https://users.soe.ucsc.edu/~abadi/CS223_F12/taly.pdf research paper on the security https://gist.github.com/pfrazee/8949363 Web Workers to isolate execution...
WASM talk: https://www.youtube.com/watch?v=DKSxcozc4w8
Options: -1. Send to an iframe to eval there and return... 0. Try wrapping the code like node.js does... https://gist.github.com/aemkei/3847852 ?
-
Wasm
-
subset of JS / interpreter / runtime written in JS
-
ajax calls to node? Q: websockets? https://60devs.com/executing-js-code-with-nodes-vm-module.html
-
interesting JS features to isolate scope https://blog.risingstack.com/writing-a-javascript-framework-sandboxed-code-evaluation/
Q: Could this work? https://github.com/JoshuaWise/expression-sandbox
https://github.com/google/closure-library