3

I'm trying to to execute some javascript box in a sandbox environment. I'm trynig several approaches, but all the library I've tryed does not work exactly like the browser. Here is a list of test I need to pass to accomplish what I need: https://github.com/jurgob/js_questions/blob/master/src/utils/evaluateCode.test.js

Basically, this inside a nominal function should be the "global" scope, and if I declare a variable without var, or with var but in the "top level". Exactly like javascript is supposed to work. (not in strict mode, obviously). Least but not least, after the execution, your application global environment (window, in the browser) should does not have the variable set (my tests are not perfectly testing this). All those requirements are more or less expressed with the tests I wrote, so I "just" need to make them "green" :)

Here is my current implementation: https://github.com/jurgob/js_questions/blob/master/src/utils/evaluateCode.js it's just a simple eval, so it doesn't fit all the tests.

here his the attemps I did:

a) I've tried the global eval, but is not isolated (btw, there's an interesting article here: http://perfectionkills.com/global-eval-what-are-the-options/)

b) I used new Function("window", "with(window){" + code + "}")({});, it solve the variable without var problem, but the this inside the function is still wrong.

c) I've used https://github.com/dfkaye/vm-shim, but the code in the it(' function this = window with res = 5;',... test is actually not sandboxed and "it(' function this = window with var res = 5;', " its failing cuz res is not assigned to the global scope

d) I tryed https://github.com/asvd/jailed, even If I don't like the idea to have iframe added to my DOM, but testing here: http://asvd.github.io/jailed/demos/web/console/ it seems not working 100% (I've opened an issue:https://github.com/asvd/jailed/issues/41

So my current Idea is that I could use acorn to bind all the funtions to the global object and execute the js in with(this), like:

  const context = {
   log
  }
  cons sCode = code // replace all "function a(){}"" with "a=a.bind(this);function a(){} "
  new Function("window", "with(window){" + sCode + "}")({});

but the implementation is not that trivial and I'm not sure is the best way to do it

Jurgo Boemo
  • 1,690
  • 1
  • 15
  • 21
  • The snippets here use an iframe-based solution as well... http://meta.stackoverflow.com/questions/269753/feedback-requested-runnable-code-snippets-in-questions-and-answers - probably the way to go. – Lucero Oct 20 '16 at 00:44
  • 1
    Possible duplicate of [How can I sandbox untrusted user-submitted JavaScript content?](http://stackoverflow.com/questions/12209657/how-can-i-sandbox-untrusted-user-submitted-javascript-content) – Lucero Oct 20 '16 at 00:46
  • Both b) and your current approach are as unisolated as a) is. – Bergi Oct 20 '16 at 03:15
  • The scenario is that I have to execute a lot of small script, and I have to be sure they don't modify the global. Scripts Trustness is not my main concern, but I must be sure that a script does not influence the execution of the next script. I'm more concerned about the performance, and an iframe solution seems a little bit heavy. @Bergi, I know, infact my current implementation does not pass my own tests :) – Jurgo Boemo Oct 20 '16 at 09:25
  • An iframe or [web worker](http://stackoverflow.com/q/10653809/1048572) will be your best bet. But if you trust the scripts anyway, what exactly is the problem? What kind of "influence" are you concerned about? – Bergi Oct 20 '16 at 13:16
  • That some variables can be setted in the global environment, changing the behavior of the scripts executed after. and , basing from the approach you choose, the behavior of declaring a variable without a var or the this returned from a function, is not working as expected.) I think this is what my tests are testing (yeah, I should test for an execption instead of window[res] === undefined, :P I will improve them) – Jurgo Boemo Oct 20 '16 at 13:21
  • @Bergi if you look the tests, they should explain it. Basically If you have some variable on window, this variable will affect the next js execution – Jurgo Boemo Jan 31 '17 at 11:23

0 Answers0