patternjavascriptModerate
Sandbox or safely execute eval
Viewed 0 times
sandboxsafelyevalexecute
Problem
In a large project of mine, I've run into a situation where a client might need to run evaluated JavaScript code. I know, it makes me cringe too. One option is to manually parse it, but for future flexibility, I would like to evaluate the code safely.
Everything I've seen and researched says, NO. Ah, the nay-sayers.
This is my attempt to sandbox the eval:
jsFiddle
Can you shoot holes in it and try and break it? I should wrap it in a try so it doesn't throw ugly errors, but beyond that, tell me where I have gone awry.
I have been unsuccessful at accessing the parent document variables, or being able to do anything obnoxious other than to my self within the sandbox.
Everything I've seen and researched says, NO. Ah, the nay-sayers.
This is my attempt to sandbox the eval:
jsFiddle
Can you shoot holes in it and try and break it? I should wrap it in a try so it doesn't throw ugly errors, but beyond that, tell me where I have gone awry.
/***************************************
* Senica Gonzalez (senica@gmail.com)
* This is an attempt to sandbox an eval
* in javascript using an iframe.
* Test it and let me know if you
* can break it.
***************************************/
window.addEventListener("message", function(event){
$('#result').text(event.data.eval);
console.log(event.data.scope1);
console.log(event.data.scope2);
}, false);
test = 'do I exist in the window?';
var input = $('[name=toeval]');
input.on('change', function(){
var val = $(this).val();
var code = btoa('\
\
\
\
var party_size = 10;\
window.parent.postMessage({\
eval: eval('+val+'),\
}, "*");\
\
\
');
var frame = $('');
var sandbox = $('#sandbox');
sandbox.html(frame);
});I have been unsuccessful at accessing the parent document variables, or being able to do anything obnoxious other than to my self within the sandbox.
Solution
Yes, I can poke a few holes in this.
Firstly, your
This means that
Firstly, your
eval() isn't actually doing much of anything here. From the perspective of the parser running the script, that line looks like this:eval(party_size < 5)This means that
party_size
- It will fail if the code is anything other than a single expression. So entering this into the textbox:
var a = 2; a; fails with a syntax error, even though this is a perfectly legitimate thing to pass to eval().
So let's assume that was just a silly oversight and you meant to do this:
eval: eval("'+val+'"),\
Well, this will succeed in actually executing chunks of code, until that code contains a quotation mark:
eval("var a = "a"; a + "b"");
at which point it will be broken again.
Now let's imagine you decided to get around this by changing this line to:
eval: eval("' + val.replace(/"/g, '\\"') + '"),\
Now you can be pretty confident that the code will run (in most cases) and that all you need to worry about at this point is malicious code (haha).
In terms of malicious code, the attacker could execute something resource intensive that hogs the CPU and RAM:
var a = []; while(true) { a.push(new Date()); console.log("gotcha!"); }
Or they might choose to carry out a CSRF-like attack:
var x = new XMLHttpRequest();
x.open("post", "https://www.mybank.com/transferMoney");
x.send("amount=10000&toAccount=34567890");
So keeping the host DOM safe is really not the only thing to worry about. There are any other number of malicious things an attacker can carry out if they're able to run code on someone's machine.
Given the above, I would stick with the assertion that eval` is evil, and it's not going to be easy to find a "safe" way to execute untrusted code.Code Snippets
eval(party_size < 5)eval: eval("'+val+'"),\eval("var a = "a"; a + "b"");eval: eval("' + val.replace(/"/g, '\\"') + '"),\var a = []; while(true) { a.push(new Date()); console.log("gotcha!"); }Context
StackExchange Code Review Q#49253, answer score: 13
Revisions (0)
No revisions yet.