Eval is evil… So what should I use instead?

An ajax request returns me a standard JSON array filled with my user's inputs. The input has been sanitized, and using the eval() function, I can easily create my javascript object and update my page...

So here's the problem. No matter how hard I try to sanitize the inputs, I'd rather not use the eval() function. I've checked google for ways to use "JSON in AJAX without eval" and have ran accross a bunch of different methods...

Which one should I use? Is there a standard, proven-secure way of doing this?

Answers:

Answer

json.org has a nice javascript library

simple usage:

JSON.parse('[{"some":"json"}]');
JSON.stringify([{some:'json'}]);

Edit: As pointed out in comments, this uses eval if you look through its source (although it looks to be sanitized first)

to avoid it completely, look at json_parse or json-sans-eval

json2.js is insecure, json_parse.js is slow, json-sans-eval.js is non-validating

Answer

I would say, once the input is sanitized, eval is the best way to go. If your server gets compromised, people will be able to send whatever scripts they want to the client anyway. So putting an eval is not a big security risk. If you are worried about people manipulating the packets before they reach the client then, again, the scripts themselves can be modified.

Don't worry about eval. But make sure to wrap it in a try...catch block so your users don't get JS errors if your JSON gets mangled.

:)

Answer

To safely convert JSON to a JS object you should use a JSON parser such as the JSON.parse() function provided by this library.

Answer

Compare to the command design pattern: http://en.wikipedia.org/wiki/Command_pattern. Given this, you can precisely define the operations a client can execute and your application will be as safe as the underlying interpretation.

Answer

If you're certain there's no injection risk, and you're not eval()ing in a loop, then use eval(). It will compare favorably to other options which will certainly be slower, might break, and will require the client to download additional code.

Answer

"stolen" from jQuery

// Try to use the native JSON parser first
return window.JSON && window.JSON.parse ?
    window.JSON.parse( data ) :
    (new Function("return " + data))();
Answer

Issue: The problem eval poses is that it executes in the global scope

eval.call(document, "console.log(this)")
eval.call(navigator, "console.log(this)")
eval.call(window, "console.log(this)")
(function(){eval.call(document, "console.log(this)")})()
>Window

Scenario:

Assume you are using individual attributes in the markup code of various document-elements such as an attribute onvisible

<img src="" onvisible="src='http://www.example.com/myimg.png';">

You would like to get all elements with this attribute, turn the onvisible-content-string into a closure and put it into an EventHandler queue. This is where the JS Function constructor comes into play.

Function === 0..constructor.constructor
>true

Function('return [this, arguments]').call(window, 1,2,3)
>Window, Arguments[3]]
Function('return [this, arguments]').call(document, 1,2,3)
>Document, Arguments[3]]
Function('return [this, arguments]').call(navigator, 1,2,3)
>Navigator, Arguments[3]]    

Putting it all together:

var eventQueue = [];
var els = document.querySelectorAll('[onvisible]');

for (var el in els) {
    var jscode = els[el].getAttribute('onvisible');
    eventQueue.push( {el:els[el], cb:Function(jscode)} )
}

//eventQueue[0].cb.call(scope, args);
Answer

Is there a standard, proven-secure way of doing this?

There is a proposed standard way of doing this, in the forthcoming ECMAScript 3.1 version of JavaScript: JSON.parse.

It will be supported in IE8, Firefox 3.1/3.5 and most likely the other popular browsers in the future. In the meantime, you can fall back to, or use exclusively, eval(). Evil it may or may not be; certainly it will be slower than JSON.parse. But that's the usual way to parse JSON today.

If an attacker is able to inject malcious JavaScript into content you are spitting out via JSON, you have bigger problems to worry about than eval-is-evil.

Answer

Depends on what you're trying to accomplish with the sanitation. I've had great success w/the prototype framework's support for JSON and safe evaluation.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.