If it were safe to use eval()
, there would be no need for a special function to parse JSON data.
Put a bit differently, try feeding the following to eval()
and your JSON parsing function, and note the difference in what happens:
0; for (var i = 0; i < 10; i++) {console.log(i)};
This obviously isn't valid JSON, so the JSON parsing function will of course reject it as invalid. The eval()
function, however, will do exactly as this perfectly valid JavaScript code says to, and log the numbers 0 through 9 to the JavaScript console (note that the 0;
at the beginning defuses syntax errors that would be caused by constructs such as your example usage of eval()
). Given this, it's pretty easy to see that eval()
is dangerous if you don't at least check that the data is valid JSON.
This, combined with the simple fact that you can never trust 100% that data you are receiving is actually in the format the source claims it is and is a valid instance of that format should be enough to demonstrate that just a bare eval()
call is not a safe way to parse JSON.
You might consider doing some simple checks and just call eval()` on the data anyway, but can you be certain that you thought of everything? By the point you get reasonably sure that you did, you've usually written about 95% of a JSON parser already, and it's just simpler (and quicker) to parse the data while you're validating it.
There are a couple of other here though that aren't exactly security problems so much as usability problems:
eval()
usually does not give very friendly errors when it fails to parse JSON data, largely because most JavaScript implementations give particularly poor errors when they fail to parse an object literal properly. In some cases, it may not even give any errors at all, because the data you're trying to read might be perfectly valid JavaScript code even though it's not valid JSON.
- Standards compliant JSON is not automatically standards compliant JavaScript. The JSON standard allows for a handful of Unicode characters to be unescaped in strings which JavaScript requires to be escaped. JSON with any of those characters un-escaped in a string will parse correctly on most JSON parsers, but not when fed to
eval()
.
- You also have to trust that the JSON document you are parsing was properly created in the first place. Aside from the above-mentioned issue with certain characters needing to be escaped inside strings in JSON, there are a couple of other edge-cases that some JSON generators don't properly account for (for example, Unicode characters above code-point U+FFFF must be escaped using UTF-16 surrogate pairs in JSON, no matter what encoding the data is actually transferred in).