Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery uses (new Function("return " + data))(); instead of eval(data); to parse JSON, why?

This link shows you that jQuery uses (new Function("return " + data))(); for older browsers, to parse a JSON string instead of eval().

What are the benefits of this? What if the JSON string isn't safe?

like image 658
Luca Matteis Avatar asked Mar 15 '10 17:03

Luca Matteis


People also ask

Is eval or new function faster?

`Function() is a faster and more secure alternative to eval().

What is the point of eval?

Answer: eval is a built-in- function used in python, eval function parses the expression argument and evaluates it as a python expression. In simple words, the eval function evaluates the “String” like a python expression and returns the result as an integer.


1 Answers

The quote in Nick's answer hints at it. It's not really a big difference, but the feeling is that eval is ‘worse’ than new Function. Not in terms of security — they're both equally useless in the face of untrusted input, but then hopefully your webapp is not returning untrusted JSON strings — but in terms of language-level weirdness, and hence resistance to optimisation.

Specifically:

function victim() {
    var a= 1;
    eval('a= 2');
    return a;
}

gives 2. The eval​ed string has operated on victim's local variable scope! This is something that a regular user-written function could never do; eval can only do it because it is dark magic.

Using a regular function instead takes away this element of magic:

function victim() {
    var a= 1;
    (new Function('a= 2;'))();
    return a;
}

in the above, the returned a remains 1; the new Function can only operate on its own local variables or the global window.a.

That knowledge allows code analysis tools — which might include JavaScript engines and particularly clever minifiers — to apply more optimisations. For example the second victim function could have the a variable completely optimised away to return 1. One use of eval and a lot of potential optimisations aren't going to be doable.

Of course in practice for a tiny function like a JSON eval​er, there isn't going to be a noticeable difference, but in general the thinking is:

  • avoid both approaches wherever possible (they are both disallowed in ECMAScript Fifth Edition's Strict Mode);
  • if you have to use one, new Function is preferable to eval, unless you really need the code to access the calling function's local variables.
like image 162
bobince Avatar answered Sep 20 '22 13:09

bobince