Categories
eval javascript security

Why is using the JavaScript eval function a bad idea?

572

The eval function is a powerful and easy way to dynamically generate code, so what are the caveats?

7

405

  1. Improper use of eval opens up your
    code for injection attacks

  2. Debugging can be more challenging
    (no line numbers, etc.)

  3. eval’d code executes slower (no opportunity to compile/cache eval’d code)

Edit: As @Jeff Walden points out in comments, #3 is less true today than it was in 2008. However, while some caching of compiled scripts may happen this will only be limited to scripts that are eval’d repeated with no modification. A more likely scenario is that you are eval’ing scripts that have undergone slight modification each time and as such could not be cached. Let’s just say that SOME eval’d code executes more slowly.

21

  • 3

    @JeffWalden, great comment. I’ve updated my post although I realize it has been a year since you posted. Xnzo72, if you had qualified your comment somewhat (as Jeff did) then I might be able to agree with you. Jeff pointed out the key: “eval of the same string multiple times can avoid parse overhead”. As it is, you are just wrong; #3 holds true for many scenarios.

    – Prestaul

    Feb 13, 2012 at 17:44

  • 7

    @Prestaul: Since the supposed attacker can just use whatever developer tool to change the JavaScript in the client, why do you say Eval() opens up your code to injection attacks? Isn’t already opened? (I’m talking about client JavaScript of course)

    Oct 24, 2012 at 1:52

  • 69

    @EduardoMolteni, we don’t care (and indeed cannot prevent) users from executing js in their own browsers. The attacks we are trying to avoid are when user provided values get saved, then later placed into javascript and eval’d. For example, I might set my username to: badHackerGuy'); doMaliciousThings(); and if you take my username, concat it into some script and eval it in other people’s browsers then I can run any javascript I want on their machines (e.g. force them to +1 my posts, post their data to my server, etc.)

    – Prestaul

    Oct 25, 2012 at 18:12

  • 3

    In general, #1 is true for quite a lot, if not most function calls. eval() shouldn’t be singled out and avoided by experienced programmers, just because inexperienced programmers abuse it. However, experienced programmers often have a better architecture in their code, and eval() will rarely be required or even thought about due to this better architecture.

    Mar 12, 2014 at 8:35

  • 4

    @TamilVendhan Sure you can put breakpoints. You can access the virtual file created by Chrome for your evaled coded by adding the debugger; statement to your source code. This will stop the execution of your program on that line. Then after that you can add debug breakpoints like it was just another JS file.

    – Sid

    Jul 25, 2014 at 22:27

353

eval isn’t always evil. There are times where it’s perfectly appropriate.

However, eval is currently and historically massively over-used by people who don’t know what they’re doing. That includes people writing JavaScript tutorials, unfortunately, and in some cases this can indeed have security consequences – or, more often, simple bugs. So the more we can do to throw a question mark over eval, the better. Any time you use eval you need to sanity-check what you’re doing, because chances are you could be doing it a better, safer, cleaner way.

To give an all-too-typical example, to set the colour of an element with an id stored in the variable ‘potato’:

eval('document.' + potato + '.style.color = "red"');

If the authors of the kind of code above had a clue about the basics of how JavaScript objects work, they’d have realised that square brackets can be used instead of literal dot-names, obviating the need for eval:

document[potato].style.color="red";

…which is much easier to read as well as less potentially buggy.

(But then, someone who /really/ knew what they were doing would say:

document.getElementById(potato).style.color="red";

which is more reliable than the dodgy old trick of accessing DOM elements straight out of the document object.)

8

  • 85

    Hmm, guess I got lucky when I was first learning JavaScript. I always used “document.getElementById” to access the DOM; ironically, I only did it at the time because I didn’t have a clue how objects worked in JavaScript 😉

    Mar 15, 2009 at 6:45

  • 5

    agree. Sometimes eval is ok e.g. for JSON responses from webservices

    – schoetbi

    Jan 3, 2011 at 15:17

  • 45

    @schoetbi: Shouldn’t you use JSON.parse() instead of eval() for JSON?

    Jan 10, 2011 at 21:46

  • 4

    @bobince code.google.com/p/json-sans-eval works on all browsers, so does github.com/douglascrockford/JSON-js . Doug Crockford’s json2.js does use eval internally, but with checks. Besides, it’s forward-compatible with built-in browser support for JSON.

    – Martijn

    Feb 1, 2011 at 10:13

  • 9

    @bobince There is something called feature-detection and polyfills to handle missing JSON libraries and other things (look at modernizr.com)

    – MauganRa

    Nov 22, 2012 at 16:04

39

I believe it’s because it can execute any JavaScript function from a string. Using it makes it easier for people to inject rogue code into the application.

11

  • 6

    What is the alternative then?

    – moderns

    May 12, 2014 at 14:06

  • 5

    Really the alternative is just write code that doesn’t require it. Crockford goes into length about this, and if you need to use it, he pretty much says that its a program design flaw and needs to be reworked. In truth, I agree with him too. JS for all it’s flaws is really flexible, and allows a lot of room to make it flexible.

    May 12, 2014 at 14:46

  • 3

    Not true, most frameworks have a method to parse JSON, and if you aren’t using a framework, you can use JSON.parse (). Most browsers support it, and if you’re really in a pinch, you could write a parser for JSON pretty easily.

    May 12, 2014 at 14:58

  • 6

    I don’t buy this argument, because it already is easy to inject rogue code into a Javascript application. We have browser consoles, script extensions, etc… Every single piece of code sent to the client is optional for the client to execute.

    Feb 4, 2015 at 14:37

  • 7

    The point is that’s it’s easier for me to inject code into your browser. Let’s say you’re using eval on a query string. If I trick you into clicking a link that goes to that site with my query string attached, I’ve now executed my code on your machine with full permission from the browser. I want to key log everything you type on that site and send it to me? Done and no way to stop me because when eval executes, the browser gives it highest authority.

    Feb 4, 2015 at 15:00