views:

320

answers:

2

Question: I'm using eval to parse a JSON return value from one of my WebMethods.

I prefer not to add jquery-json because the transfer volume is already quite large. So I parse the JSON return value with eval.
Now rumors go that this is insecure. Why ?

Nobody can modify the JSOn return value unless they hack my server, in which case I would have a much larger problem anyway.

And if they do it locally, JavaScript only executes in their browser.
So I fail to see where the problem is.

Can anybody shed some light on this, using this concrete example?

function OnWebMethodSucceeded(JSONstrWebMethodReturnValue) 
{
    var result=eval('(' + JSONstrWebMethodReturnValue + ')')
    ... // Adding result.xy to a table
}
+9  A: 

The fundamental issue is that eval can run any JavaScript, not just deserialize JSON-formatted data. That's the risk when using it to process JSON from an untrusted or semi-trusted source. The frequent trick of wrapping the JSON in parentheses is not sufficient to ensure that arbitrary JavaScript isn't executed. Consider this "JSON" which really isn't:

function(){alert('Hi')})(

If you had that in a variable x and did this:

var result = eval("(" + x + ")");

...you'd see an alert -- the JavaScript ran. Security issue.

If your data is coming from a trusted source (and it sounds like it is), I wouldn't worry about it too much. That said, you might be interested in Crockford's discussion here (Crockford being the inventor of JSON and a generally-knowledgeable JavaScript person). That page also has a link to his json2.js parser and stringifier, which when minified are only 2.5k in size, so you might consider using them. The parser still uses eval, it just takes several precautions first.

T.J. Crowder
+3  A: 

Increasingly, JSON parsing and encoding is available natively in modern browsers, [wikipedia reference] This gives your application secure JSON functionality without needing to load an additional library.

You can test for native JSON support by doing something like this:

var native_JSON_exists = typeof window.JSON === 'object';

You should load up a JSON parsing library like Douglas Crockford's one (linked by T.J. Crowder, above) or functionality available via a framewok for browsers that don't have native support. (But you should at least use native JSON in browsers that support it, to protect users lucky enough to have modern browsers)

Bear in mind, JSON is a subset of JavaScript's syntax so strings that work in an JavaScript eval statement may not work in proper JSON parsing. You can test your JSON strings for errors using JSLint (http://www.jslint.com/).

adamnfish
+1 Sadly, though, native support isn't really ready for prime time yet; too many implementation bugs (surprisingly). But it'll get there.
T.J. Crowder