Local Eval
Evaluate a string of JS code without access to the global object.
Always use that instead of eval()
. Always.
API:
localeval(code :: String, sandbox :: Object) :: Object.
localeval(code :: String, sandbox :: Object,
timeout :: Number, cb :: Function)
The code
is a string of JS code. The sandbox
contains objects which are
going to be accessible in the JS code.
It returns the last evaluated piece of JS code in code
, if no timeout is
given. Otherwise, after at most timeout
milliseconds, the callback gives that
result as a parameter: function(error, result) {…}
.
Node example:
var localeval = ;; // Throws.localevalclear; // Kills processes used internally.
Browser example:
<!-- Alerts "32". -->
You may find an example of use in browser code in main.html
.
Purpose
Trying to find a reasonable cross-environment ES5 sandbox evaluation function.
Offering a process-separated timeout-ed VM for node.
Warning
If no timeout is given, it doesn't protect your single-threaded code against infinite loops. Additionally, the following leak:
({}).constructor.getOwnPropertyNames = function(){return 'leak';}
Function("this.foo = 'leak'")()
If a timeout is given, an attacker can still use XHR:
Function("this.XMLHttpRequest(…); …")()
That said, it protects against any security leak.
-
All local and global variables are inaccessible.
-
Variables defined while evaluating code don't pollute any scope.
-
Evaluated code cannot fiddle with global object's properties. Think
localeval('([]).__proto__.push = function(a) { return "nope"; }')
.
Things to try
In comments are what should be executed outside the sandbox.
Stringprototype { return 'leaked'; };// 'nice'.slice(1) === 'ice'String { return 'leaked'; };// String.fromCharCode(42) === '*'// var foo = 1foo = 7thisfoo = 7windowfoo = 7// foo === 1delete NumberparseInt// Number.parseInt('1337') === 1337Stringprototype { return 'leak'; }// try { ''.leak() } catch(e) { /not a function/.test(e.message) }
This work is licensed under the Creative Commons Attribution 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/.