JSON.Parse VS. Eval()

JSON.parse vs. eval()

You are more vulnerable to attacks if using eval: JSON is a subset of Javascript and json.parse just parses JSON whereas eval would leave the door open to all JS expressions.

Difference between JSON.parse() and eval()

Your problem is that you mixing two unrelated things.

eval() is built-in javascript function, which main purpose is to interpret string of javascript code (thus make potentional security hole)

JSON.parse() function is for parse JSON string. Although very simmilar, do not make mistake, JSON is not Javascript and there are tiny differences. You should not use eval() for parsing JSON

What are the differences between JSON and JavaScript object?

Does JSON.parse() use eval() internally?

No, JSON.parse() doesn't Use eval()

This is by design, as eval() being able to execute any arbitrary JavaScript code you feed it, it could execute things you wouldn't want it to. So JSON.parse() does what it says on the tin: it actually parses the whole string and reconstructs and entire object tree.

JSON.parse is usually delegated to an internal function implemented with "native" code, where "native" means whatever is considered "native" in the context of your browser's javascript engine (could be compiled machine code, could be bytecode for a VM, etc...). I don't think there's any strong requirement on that.

Differences in the Implementations?

JSON (the notation) itself is codified by the RFC4627.

Regarding the implemetation of the JSON object and its methods, all modern browsers implementing should behave the same, as they should follow the same specifications for ECMAScript 5's JSON object. However, there's always the chance for potential defects. For instance, V8 originally contained this nasty bug.

Also, note that the implementation listed in comments above are for you to add JSON.parse() support to browsers that do not support it natively (also known as "these damn old browsers you sometimes need to support"). But it doesn't mean that it's necessarily how they implemented it.

For instance, for Google's V8 implementation used in Chrome, see json.js which invokes native code from json_parser.h.

Is JSON.parse() really safer than eval() when web page and ajax call come from same server?

Yes, it is really safer. Every precaution you do not take is a set of potential exploits you don't prevent.

An attacker might be able to have some control over your server's output without being able to change it entirely. Nobody's suggesting it's a magic bullet, but it's potentially faster and you're not creating a potential vulnerability that could come back and hurt you.

Maybe someone running your server is having a bad day, and does something silly like constructing JSON by concatenating unsanitized user input:

<?php
print '{"foo": ' . $_GET['bar'] . '}';
?>

If you're using JSON.parse, the worst they can do is shove a large object into your memory. If you're using eval they can hijack everything.

eval() works but JSON.parse() and $.parseJSON() doesn't work

In JSON, object keys are type "string", and thus need to be quoted. Your keys are unquoted.

Your web browser is kind enough to allow unquoted strings.

Convert eval() to JSON.parse

Just replace that line with:

var jsonData = JSON.parse(request.responseText);

Provided the response is proper JSON, this should just work.

eval does not work, but JSON.parse does

That buggy character is U+8232, the Unicode LINE SEPARATOR. It leads to "unterminated string literal" syntax errors in various browsers, this is why it does not work to eval() the string. JSON.parse can work around that, as JSON is not really a JS subset in that perspective.

JSON Data - Parsed Or 'Eval'ed

Here's what the official JavaScript parser does:

// In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with '()' and 'new'
// because they can cause invocation, and '=' because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms.

// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.

if (/^[\],:{}\s]*$/.
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {

// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.

j = eval('(' + text + ')');

...

With the exception of the built-in JSON parsing support that is in modern browsers, this is what all (library-based) secure JSON parsers do (ie, a regex test before eval).

Secure libraries (in addition to the official json2 implementation)

Prototype's isJSON function.

Mootools' JSON.decode function (again, via a regex test before eval).

Unsecure libraries:

dojo's fromJson does not provide secure evaling. Here is their entire implementation (minus comments):

dojo.fromJson = function(json) {
return eval("(" + json + ")");
}

jQuery does not provide secure JSON eval'ing, but see the official plugin's secureEvalJSON function (line 143).



Related Topics



Leave a reply



Submit