Feb 25, 2011

The evil magic of eval

Eval is a special, very powerful function in many scripting languages. JavaScript is not an exception. Although quite useful for dynamic manipulation of the existing code, any misuse of eval can cause a lot of problems and headaches. StackOverflow covers this topic well, with the exception of one very important bit: eval can get in the way of testability.

Static analysis
With JavaScript being what it is, it is easy to assume that one can painlessly audit the scripting code that runs inside the browser and understand how the client-side part of a web application functions. Well, that's not entirely true. With web applications becoming more complex, we often run into cases where we have a 60k line obfuscated code that looks a lot like this:
function a() {
this.c = eval;
}
...
var b = a();
var d = b.c(e);

How should this be tested or audited? Simple answer: you can't really or at least not easily.

Dynamic analysis
This leads me to the next bit: what about dynamic analysis? What if we "hook" into eval and listen to the code as it goes by? As it turns out, this isn't a fool proof solution either. Eval is not exactly a function. In fact, if you ask any experienced developer, he/she may flat out tell you that eval is magic and should not be touched. To re-use the example from StackOverflow, what value should the alert box show?
var a = 10;
function foo() {
var a = 1;
eval("a+=1");
alert(a);
}
foo();

As it turns out, eval is aware of the current scope from which it was called; therefore the alert box will show 2 and not 11. This is important because as you overload eval, you change the scope in which it operates (off by 1 stack frame). As a result eval will attempt to manipulate a global object and not the local one. This in turn may lead to a half baked page.

Conclusion
Although eval is very powerful, it is also overly misused for parsing and/or processing data (example: using eval to parse JSON). In a nutshell, eval provides one of the easiest ways to mix code and data... a dangerous thing to do nowadays.

P.S. - Although some browsers (namely Firefox) may allow you to overload eval at a lower level through an extension, it is not necessarily the same case with all mainstream browsers; therefore, some edge cases may be missed.

No comments: