Use of eval () in javascript: what are the pros and cons?

23

I recently knew this function and I was surprised by its power, it was very useful to me, but after using it I heard comments that it was not safe.

I would like to know if this usage can cause security problems and if there is an alternative to eval () when you want to generate javascript code dynamically, but in a more secure way.

Example usage by my application:

var valPeriodos = "";
var next = ".next()";

for (i = 1; i <= numPeriodos; i++) {
    eval('var tdVal' + i + '=$(this).parent().parent().find(".vp1").parent()' + valPeriodos + ';');
    valPeriodos += next;
    eval('val_' + i + ' = tdVal' + i + '.find(".valInputOn").val()');
}

In this code I get values from a PivotTable that have columns according to the number of periods and save them in variables.

    
asked by anonymous 04.02.2014 / 19:48

3 answers

11

I also have to answer because eval () is not as bad as many people think, it depends on how and where you use it. Driving a car is dangerous if you do not know how to do it.

For those who do not master javascript eval can scare you. And then it is easier to generalize and say that you should never use it. This is not the case.

eval is one of the most powerful tools in javascript. It is a parser itself. The biggest problem of eval arises when connected to communication with the server. But if you use eval in internal code functions, without external input eval can be very useful and secure.

It is worth mentioning (and taking into account) that any user can reach a website, open the console and run malicious code with eval.

In case you have eval in lines of code that connect to a database for example, it is important to make blinds possible attacks. In these cases avoid eval.

The first part of my answer is positive to eval, to say that there are cases where it is useful ( like here for example ).

But he has cons of weight:

  • Misuse of eval can lead to code-injection attacks

  • Slower than similar code without eval

  • Difficulties and limits minification of the code

  • Finally it is worth mentioning that eval is used in hidden javascript. More about this on this question .

        
    03.08.2014 / 22:52
    13

    eval , in certain situations causes your code to be ...

  • ... more difficult to understand: javascript is being compiled on the fly, which, in addition to letting it slow down, causes it to vary depending on the variable that is entered in the function;
  • ... most insecure: ever heard of SQL Injection ? eval is an open door to this, only in another language;
    Using 'use strict' prevents an attacker from accessing private variables, but it does not protect global variables, so if you have to use eval validate the code before executing it.
  • ... more difficult to work with: tools like Closure Compiler and Uglify are unable to work with eval in certain situations. The function prevents these tools from encountering the defined variables and arranging them.
  • But there are situations where eval is accepted - according to the Google style :

    • If you are programming a REPL, for example:
    !function r(i){i=prompt('Insira um comando:');if(i)alert(eval(i)),setTimeout(r)}()
    
    • If you are programming a code loader: RequireJS , for example, use eval .

    Editing: A code sample was added to the question, this answer even rewritten code without using eval .

        
    04.02.2014 / 20:05
    2

    In the example you gave, the alternative to eval would be to use a vector rather than a bunch of separate variables:

    var vals = [];
    var tdVals = [];
    var tdAtual = $(this).parent().parent().find(".vp1").parent()
    //Vetores em Javascript são normalmente indexados começando do zero então mexi no seu loop.
    for (i = 0; i < numPeriodos; i++) { 
        tdVals[i] = tdAtual;
        vals[i] = tdAtual.find(".valInputOption").val();
        tdAtual = tdAtual.next();
    }
    

    Some of the advantages this code has compared to the version using eval:

    • It will be easier to debug. In case of an error, the debugger points the code line better, you can mark breakpoints, inspect the contents of the variables, etc.
    • It will be easier to use tools that analyze your code without executing it, like JSHint (strongly recommend using such a thing if you are not using it!). Usually these tools get totally lost if they find an eval.
    • Vectors are a first-class object in JS, unlike their dynamic variables. You can move them from side to side, you can look at tdVals.length instead of having to keep numPeriodos separately, etc.
    • The scope of your variables becomes clearer. You can see the names of the two vectors I'm creating and it's easier to know if the variables are global and local.
    • The algorithm has become simpler and more efficient. Now it gives a next only for each td instead of 1 for the first, 2 for the second, etc.
    • I think it's easier to understand. Code using eval can potentially do anything, which means it has to be read more closely.
    04.02.2014 / 20:19