Using JavaScript eval to parse JSON

2019-02-17 03:31发布

问题:

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
}

回答1:

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). Crockford also provides at least three public domain parsers on this page you might consider using: His json2.js parser and stringifier, which when minified is only 2.5k in size, but which still uses eval (it just takes several precautions first); his json_parse.js, which is a recursive-descent parser not using eval; and his json_parse_state.js, a state machine parser (again not using eval). So you get to pick your poison. (Shout out to Camilo Martin for pointing out those last two alternatives.)



回答2:

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/).