301

I'm writing some JavaScript code to parse user-entered functions (for spreadsheet-like functionality). Having parsed the formula I could convert it into JavaScript and run eval() on it to yield the result.

However, I've always shied away from using eval() if I can avoid it because it's evil (and, rightly or wrongly, I've always thought it is even more evil in JavaScript, because the code to be evaluated might be changed by the user).

So, when it is OK to use it?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Richard Turner
  • 12,506
  • 6
  • 36
  • 37
  • 7
    Most JSON libraries do not, in fact use eval under the hood, exactly to protect against the security risks. – Sean McMillan Dec 14 '09 at 17:23
  • 13
    @Sean - Both JQuery and Prototype use eval (JQuery uses it via new Function) – plodder Apr 19 '10 at 22:53
  • 8
    @plodder - Where are you getting your info? jQuery has utilized the native JSON.parse() since 1.4 (way back in 1/2010)! See for yourself: http://code.jquery.com/jquery-1.4.js – ken Jan 04 '11 at 18:38
  • 1
    @ken,Sean it uses JSON.parse _if it is available_ this is not the case for IE<=7 – tobyodavies Jan 27 '11 at 03:54
  • @tobyodavies - good point, except saying IE<=7 is misleading, since ANY browser more than a few years old won't have a native JSON object. and the point I was trying to make, is that JS libs don't _prefer_ `eval()`....it's just a fallback for *legacy* browsers. – ken Jan 27 '11 at 04:52
  • @ken, also good point, however IE6 & IE7 are still in very widespread use, i'd call them old, not sure about legacy - they are far from dead, unfortunately. definately they don't prefer it, but they do use it in some situations, thus they believe it is safe enough with some constraints. – tobyodavies Jan 27 '11 at 05:35
  • Another more javascript-centric discussion on this topic is at http://stackoverflow.com/questions/4812288/why-is-eval-unsafe-in-javascript/4812341 – tobyodavies Jan 28 '11 at 09:28
  • 4
    *"Obviously one has to use eval() to parse JSON"* -- this is not true, on the contrary - one *shouldn't use eval to parse JSON!* Use Douglas Crockfords' (creator of JSON) json2.js script from http://www.json.org/! – Tomas Apr 25 '12 at 23:47
  • 17
    @Tomas the irony there being that json2.js uses eval to parse JSON – tobyodavies Jun 08 '12 at 02:01
  • 1
    @Tomas, +1. In fact, you can't use `eval` to correctly parse all JSON strings. `JSON.parse(' "\u2028" ')` works but `eval(' "\u2028" ')` fails with an exception because U+2028 is a JavaScript newline but is allowed in JSON unescaped. – Mike Samuel Aug 03 '12 at 22:40
  • 1
    Using `eval` can reveal your library implementation code, because it runs from the closure. Performance hit is also big, because it parses and compiles every time. With `Function` constructor this can be avoided. `Function` constructor run in Global closure independently of where it is invoked. If you plan to call this function several times, it may become "hot" and JavaScript engine optimize it. And since it returns a function object you may store it in cache to limit the calls to `Function` constructor. – Plamen Dragiyski Dec 21 '14 at 11:54
  • 2
    "to parse user-entered functions (for spreadsheet-like functionality)" suggests to me that much of the eval concern here is unwarranted. Assume the function is not persisted to the DB, what harm can a javascript function have on the single user single page level? Hacking his/her own data? If persisted and not shared, again, concern scoped to the user. Persisted and shared (or viewed by others), yep, you have a XSS injection vector. – Jed Schneider Mar 14 '18 at 18:31
  • 1
    `eval` is always evil. There are no exceptions period. When you want to evaluate code, use `window.Function`. Sure there are cases where you can do stuff with eval that cannot be done otherwise, but those are illegitimate use cases that should never be performed by any self respecting coder. – Jack G May 21 '18 at 20:30
  • 1
    Mozilla makes it perfectly clear: [Do not ever use eval!](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Do_not_ever_use_eval!) – Ruud Helderman Jul 13 '19 at 23:16
  • 1
    Don't forget that eval is incompatible with every tool you can think of, ESLint, Prettier, UglifyJS, most editors/IDE features... and your collegues won't like it if they are professional. Finding a hacky way to do something might seem clever to solve an immediate problem, but it's not in the long run. – Rivenfall Sep 03 '20 at 23:27

27 Answers27

284

I'd like to take a moment to address the premise of your question - that eval() is "evil". The word "evil", as used by programming language people, usually means "dangerous", or more precisely "able to cause lots of harm with a simple-looking command". So, when is it OK to use something dangerous? When you know what the danger is, and when you're taking the appropriate precautions.

To the point, let's look at the dangers in the use of eval(). There are probably many small hidden dangers just like everything else, but the two big risks - the reason why eval() is considered evil - are performance and code injection.

  • Performance - eval() runs the interpreter/compiler. If your code is compiled, then this is a big hit, because you need to call a possibly-heavy compiler in the middle of run-time. However, JavaScript is still mostly an interpreted language, which means that calling eval() is not a big performance hit in the general case (but see my specific remarks below).
  • Code injection - eval() potentially runs a string of code under elevated privileges. For example, a program running as administrator/root would never want to eval() user input, because that input could potentially be "rm -rf /etc/important-file" or worse. Again, JavaScript in a browser doesn't have that problem, because the program is running in the user's own account anyway. Server-side JavaScript could have that problem.

On to your specific case. From what I understand, you're generating the strings yourself, so assuming you're careful not to allow a string like "rm -rf something-important" to be generated, there's no code injection risk (but please remember, it's very very hard to ensure this in the general case). Also, if you're running in the browser then code injection is a pretty minor risk, I believe.

As for performance, you'll have to weight that against ease of coding. It is my opinion that if you're parsing the formula, you might as well compute the result during the parse rather than run another parser (the one inside eval()). But it may be easier to code using eval(), and the performance hit will probably be unnoticeable. It looks like eval() in this case is no more evil than any other function that could possibly save you some time.

user27476
  • 2,936
  • 1
  • 16
  • 3
  • 82
    You're not addressing the issue of code that uses eval being difficult to debug – bobobobo Aug 29 '09 at 18:45
  • There is a more complete answer to this question here http://stackoverflow.com/questions/951373/when-is-eval-evil-in-php – bobobobo Aug 29 '09 at 18:46
  • 57
    Code Injection is a very serious issue for javascript if you are at all concerned about your user's data. Injected code will run (in the browser) as if it came from your site, letting it do any sort of shenanigan that the user could do manually. If you allow (third-party) code to enter you page, it can order things on behalf of your customer, or change their gravatar, or whatever they could do through your site. Be very careful. Letting hackers own your customers is just as bad as letting them own your server. – Sean McMillan Dec 14 '09 at 17:19
  • 76
    If the data is comming from your server and its something that you, the developer has generated, there is no harm in using eval(). The real harm is beliving everything you read. You see lots of people saying eval() is evil and they have no idea why except that they read it somewhere. – Razor Mar 04 '10 at 05:38
  • 47
    @Sean McMillan: I want to believe you, but if someone is going to intercept and change javascript going to `eval()` from your server, they could also just change the page's source in the first place, and also take control of the user's information . . . I don't see the difference. – Walt W Apr 01 '10 at 17:25
  • @user27476 -- I agree that if one is going to parse the string, then one may as well go ahead and do the calcs. It's what I would do, but maybe that's just me. – Pete Wilson Jan 12 '12 at 21:36
  • On Chrome, here are some performance comparisons between direct code, evel of that code, and Function(code)() (same thing as eval): http://jsperf.com/eval-vs-parse-and-call/2 – Devin Rhode Apr 08 '12 at 08:19
  • 23
    Re "Code injection - ... Again, JavaScript in a browser doesn't have that problem," & " Also, if you're running in the browser then code injection is a pretty minor risk, I believe." Are you suggesting that code-injection in the browser is not a problem? XSS has been in the top 3 vulns on OWASP's top 10 list for several years running. – Mike Samuel Aug 03 '12 at 22:42
  • 8
    @MikeSamuel, XSS only works if you can inject code into _someone else's browser_ ("Cross-site scripting (XSS) is a type of computer security vulnerability… that enables attackers to inject client-side script into Web pages viewed by other users." [Wikipedia](http://en.wikipedia.org/wiki/Cross-site_scripting)). So if you eval code that the user has entered on the same page, no harm, no foul. If you allow visitors to leave unsanitized comments, you're opening the door for them to leave cuckoo's eggs. – thirdender Aug 30 '12 at 15:18
  • 3
    @thirdender, What leads you to believe that the string reaching `eval` contains no chars controlled by another user? The original question never states that the spreadsheet is viewable only by one user. – Mike Samuel Aug 30 '12 at 16:10
  • 2
    @MikeSamuel, each case needs to be handled separately. That's why I said it's important to sanitize user input. In and of itself though, I think "eval is evil" isn't true. However, if you find yourself in a situation where you think `eval` is your only solution, you should stop and think. If it can be avoided, it's probably better to do so, but not at all costs. Also, it's worth noting that Douglas Crockford (of "eval is evil" fame) decries block-less statements and `++`/`--` operands only two pages after `eval` ([Javascript: The Good Parts](http://shop.oreilly.com/product/9780596517748.do)). – thirdender Aug 30 '12 at 19:39
  • 1
    @thirdender, I think you're confusing me with someone who said "eval is evil." – Mike Samuel Aug 30 '12 at 19:50
  • 10
    "JavaScript in a browser doesn't have that problem, because the program is running in the user's own account anyway" - this doesnot entirely capture the issue with using eval. If the script entered by one user is eval()ed at another, that can wreak havoc. And the answer appears to not care about this. – akkishore Dec 27 '12 at 08:31
  • 1
    That really isn't an issue with eval as much as it is how you setup user interactions. Users should have sanitized strings served up to them (if there is any user generated content being shared) I really don't see how this is eval's fault, sure there are dangers of using it, but that has nothing to do with eval, if you're allowing user generated content there are a lot of other evil things your users can do outside of abusing a poorly secured usage of eval – Mike Apr 08 '15 at 17:14
  • @bobobobo: in fact, `eval()` can help debugging. See my post below http://stackoverflow.com/questions/197769/when-is-javascripts-eval-not-evil/17809716#17809716 – Benjamin Sep 19 '16 at 11:20
  • 3
    On code injection: The amount risk involved is reliant on how exactly the eval function is used. `eval("alert('hello')")` poses no more risk than `alert('hello')` because in both cases an attacker would need to change the source to change anything. However if something like eval("users['" + username + "']") could be tremendously dangerous because an attacker would simply need to fashion a clever username and they'd be able to run code on other users' behalf. tl;dr `eval` is not evil. `eval` + bad programming is evil. – Samie Bencherif Nov 27 '16 at 20:25
  • "JavaScript in a browser doesn't have that problem, because the program is running in the user's own account anyway." Unless the JavaScript is "install this evil malware on the machine" and the user has privileges to do it. – jpmc26 Apr 19 '17 at 04:30
  • I have an internal-use-only app that I thought of using eval() in to create functions based on a JSON file I supply. The functions only affect the enabling, nulling, etc of UI fields so even if the JSON were compromised it would only break the UI. If they also change the .js file then they already have full control. It would be much less code... In retrospect, I should have done it. – Jonathan Rys Nov 02 '17 at 23:02
  • Performance: you could just have `eval` create a function that'll do the work - the code will be compiled only once (or use `new Function`) – Déjà vu Nov 08 '17 at 14:05
  • To the dude speaking about code injection that got 40+ upvotes....no. Anyone who has access to your site before a user touches it can run code on your site and can drop their own js that affects the user's data without your permission and doesnt need an eval to do so. Anyone who injects js AFTER a user has touched it can STILL drop their js on your page without an eval. This is kinda what you do with chrome extensions using content scripts and also with headless browsers or plain old dev tools. Crap you can do is endless. Im still waiting to see a single example of client-side js eval evil –  Nov 12 '18 at 21:13
  • @AaronLoften Hackers are not gods. They don't have your admin password. They silently scrape your website for tiny bits of information and weaknesses. They could even use social engineering to fill in the blanks. No single bit of intel has any serious impact, but all combined, it may become a real security breach. Injections (including `eval`) are the cherry on the cake; these make the attack complete. Google, Facebook, but also big webshops and banks, have to deal with this on a daily basis. Why you don't read more about this? Because companies don't like to spill their guts. – Ruud Helderman Jul 14 '19 at 21:09
  • 1
    wonder why nobody raised this, Using `eval()` restrict JS engines from doing any optimization for that block of code which they generally do during compilation since `eval()` code can only be evaluated during run time, so browser engines will be a pessimist and just doesn't go through optimization process since it cannot predict anything. For more info -> https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/scope-closures/ch2.md#performance – Sasuke_214 Nov 05 '19 at 09:32
  • 1
    This is very irresponsibe, dangerous advice: "if you're running in the browser then code injection is a pretty minor risk, I believe" – Robert Monfera May 03 '21 at 11:38
80

eval() isn't evil. Or, if it is, it's evil in the same way that reflection, file/network I/O, threading, and IPC are "evil" in other languages.

If, for your purpose, eval() is faster than manual interpretation, or makes your code simpler, or more clear... then you should use it. If neither, then you shouldn't. Simple as that.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Shog9
  • 156,901
  • 35
  • 231
  • 235
  • 6
    One such purpose might be to generate optimized code that would either be too long or too repetitive to write by hand. The kind of stuff that, in LISP, would call for a macro. – wberry Mar 25 '14 at 15:39
  • 9
    This is such general advice that it could be applied to literally any block of code that exists. It really doesn't add anything to this question; in particular, it doesn't help anyone coming here determine whether or not their particular usage is problematic or not. – jpmc26 Oct 04 '16 at 18:29
  • 7
    Faster, simpler, more clear... This answer does not cover the security implications well enough. – Ruud Helderman Jul 14 '19 at 20:28
  • This advice _does_ add to the question the questioning of the premise of any tool being "evil". For that it gets my upvote. – capr Oct 16 '22 at 08:30
64

When you trust the source.

In case of JSON, it is more or less hard to tamper with the source, because it comes from a web server you control. As long as the JSON itself contains no data a user has uploaded, there is no major drawback to use eval.

In all other cases I would go great lengths to ensure user supplied data conforms to my rules before feeding it to eval().

Tomalak
  • 332,285
  • 67
  • 532
  • 628
  • 14
    A json string should always be tested against the json grammar before using it in eval(). So the json string "{foo:alert('XSS')}" would not pass since “alert('XSS')” is not a proper value. – Gumbo Feb 11 '09 at 12:52
  • Or when the environment is secure. – Eli Grey Oct 21 '09 at 00:30
  • But can you ever really trust the source when you're using a protocol that is susceptible to man-in-the-middle attacks? – Justin Johnson Dec 15 '09 at 18:13
  • 3
    Well, use HTTPS, then. OTOH: man-in-the-middle is not the typical attack scenario for the garden variety web app, whereas i.e. cross-site-scripting is. – Tomalak Dec 15 '09 at 18:50
  • 7
    `eval` will also not correctly parse all valid JSON strings. For example `JSON.parse(' "\u2028" ') === "\u2028"` but `eval(' "\u2028" ')` raises an exception because U+2028 is a newline in JavaScript but it is not a newline as far as JSON is concerned. – Mike Samuel Aug 03 '12 at 22:36
  • 1
    @Justin - if the protocol is compromised, well, typically the initial page load would have been sent over that same protocol, and then it's a moot point because the client is already as compromised as it can possibly be. – antinome Nov 06 '13 at 18:38
  • "In case of JSON, it is more or less hard to tamper with the source, because it comes from a web server you control." Unless you build a REST API service in nodejs. And even if you are in control, you are introducing a vulnerability that makes the ideal stepping stone into 'secure' user sessions once that trusted server happens to become compromised. Hackers thrive on this kind of naivety. Fortunately, there are good alternatives for `eval` nowadays. – Ruud Helderman Jul 14 '19 at 20:20
  • Node.js or something else on the server end has absolutely nothing to. do with it. There is no inherent vulnerability in node. When your server is compromised it's completely irrelevant whether you use JSON or anything else, so your argument is a bit circular. – Tomalak Jul 16 '19 at 21:42
26

Let's get real folks:

  1. Every major browser now has a built-in console which your would-be hacker can use with abundance to invoke any function with any value - why would they bother to use an eval statement - even if they could?

  2. If it takes 0.2 seconds to compile 2000 lines of JavaScript, what is my performance degradation if I eval four lines of JSON?

Even Crockford's explanation for 'eval is evil' is weak.

eval is Evil, The eval function is the most misused feature of JavaScript. Avoid it

As Crockford himself might say "This kind of statement tends to generate irrational neurosis. Don't buy it."

Understanding eval and knowing when it might be useful is way more important. For example, eval is a sensible tool for evaluating server responses that were generated by your software.

BTW: Prototype.js calls eval directly five times (including in evalJSON() and evalResponse()). jQuery uses it in parseJSON (via Function constructor).

Liam
  • 27,717
  • 28
  • 128
  • 190
plodder
  • 2,304
  • 18
  • 19
  • 10
    JQuery uses the browser's builtin JSON.parse function if available (which is much faster & safer), using eval only as a fallback mechanism. The statement "eval is evil" is a reasonably good guideline. – jjmontes Sep 12 '11 at 13:21
  • 37
    Re "Every major browser now has a built in console...". Code injection is a problem when one user can enter code that is then run in another user's browser. Browser consoles do not by themselves allow one user to run code in another users browser so they are irrelevant when deciding whether it is worth protecting against code injection. – Mike Samuel Aug 03 '12 at 22:29
  • 35
    "Every major browser now has a built in console ... why would they bother to use an eval statement?" - You are way off the mark. I suggest you edit the answer. Ability of one user to inject code that can run in another's browser is a major issue. And this is where you need to get really real. – akkishore Dec 27 '12 at 08:24
  • 3
    Who is Crockford anyway? You are right, attacker can use any HTTP leach tool to mimic browser and do anything, he doesnt need EVAL. – Akash Kava Apr 19 '13 at 10:29
  • 7
    @akkishore, I will appreciate if you come up with a real life example that supports your over stated statements. – Akash Kava Apr 19 '13 at 10:31
  • 1
    @AkashKava DNS poison/MITM, intercept & edit the eval()ed data and ka boom! – akkishore Apr 19 '13 at 15:17
  • 3
    @akkishore, this has nothing to do with EVAL, it means that you did not secure your DNS or proxy or whatever, remember more then browser, attacker has many tools to harm other than EVAL, writing such words doesnt prove anything, show me a working code, that is evil in EVAL, do it on any secure DNS. If browser or client's machine is compromised, EVAL is not the evil still. – Akash Kava Apr 19 '13 at 16:08
  • @AkashKava Lets make it simple. Do you suggest we design our API/interfaces to accept executable code as input that gets executed without sanity checks? For those speaking that you can use Console to do call any kind of function, please note that closures that are available to eval'ed code may not be available to Console do what you may! – akkishore Apr 19 '13 at 16:25
  • @akkishore, what harm could it do on browser? yes if its on server side code, like php or ruby on server or c# on server, then yes it has to be checked for security. Lets say anything I type in this comment box will be evaluated, what harm it will do to stack overflow server? nothing. It is your server side code that needs to be secure, browser is anyway highly secure as it does not offer any native connectivity in any form. In general EVAL on outside sandbox is evil, but inside sandboxed browser, it has no harm. – Akash Kava Apr 19 '13 at 16:36
  • 2
    @AkashKava, I think the others here have hinted at it, but eval really is a problem. A cross-site scripting (XSS) attack is where an attacker causes JS code to be run in the context of another user's browser. What can they do with that, you might think? They can steal your session and impersonate you on that site. They can post spam comments. They can harvest your personal information. Imagine that this happened on a bank website: they could steal your account numbers and balances. I suggest you read https://en.wikipedia.org/wiki/Cross-site_scripting. – Brian Donovan Feb 06 '14 at 16:04
  • @BrianDonovan how is it possible now adays? Which browser allow you to run js in context of other domain. The article is history, http only Cookie hides session & cookies from js. All major browsers guard private information very well. Point is little knowledge is more dangerous. You might not use EVAL & don't apply http only to cookies that is more harmful. Not using EVAL will not solve any problem, your server security should be tight irrespective of EVAL. – Akash Kava Feb 07 '14 at 04:18
  • 3
    @AkashKava, Server security is important but it is not the only part of the story. Also, we're not talking about running code in the context of another domain, we're talking about causing HTML to be injected into the browser *of another user on the same domain*. For example, if you run a site that allows people to post comments using a subset of HTML you have to be extremely careful not to allow HTML like this: `
    `. This is not simple. If you allow that HTML to be run in another user's browser the attacker can do bad things as I mentioned in my last comment.
    – Brian Donovan Feb 10 '14 at 17:25
  • 10
    @AkashKava What you're failing to realize, is that if I submit javascript in my comment box, and that javascript makes it to the database. When another user views that comment (that I put javascript in), eval will take that javascript when it is rendered, and evaluate it using the interpreter, causing my embedded javascript to execute on the other user's browser. By doing this, I can gleen all sorts of information. Their username, their user id in the database, their e-mail address, etc. This is not a hard answer, if you had Googled XSS, you would see in about 10 seconds why it's an issue. – Kyle Richter Aug 05 '14 at 22:43
  • 2
    This answer is so incredibly wrong that I'm shocked it got any upvotes at all. Eval JSON? Are you crazy? Ever heard of parsers or code injection? – Francois Bourgeois Jan 22 '16 at 10:00
  • @KyleRichter, there you are, when JavaScript makes it into database, this is perfect example of your weak server side security. An attacker can easily use anything else except browser even simple `curl` could send JavaScript into database. Its not `eval` that is dangerous, it is your weak security that allows code to get into database, which causes all problems, which by the way, an attacker can do even without `eval`. – Akash Kava Jun 09 '16 at 06:05
  • 4
    @AkashKava I don't know why I'm even dignifying this with a response, but I am. Javascript in a string is not harmful in and of itself, but using eval will cause that javascript to RUN, whereas otherwise it will be interpreted as a string, which will not get parsed. I don't disagree that there should be server-side escaping going on, however, using eval is just ASKING for someone to find a way to exploit the field. No matter how you argue this, it DOES introduce a security risk, and IS bad practice. Period. This is why everyone here is echoing what I said about NOT using eval. – Kyle Richter Jun 09 '16 at 18:22
  • 1
    @AkashKava One more thing. eval() is useful when, and only when, you can GUARANTEE that the ONLY possible input is javascript which YOUR application generated. Even then, it's only useful because there isn't a BETTER option. Prototype.js used eval because it was the only thing available to them for their requirement, and they did it in places in which they KNEW the integrity of the code was pure. – Kyle Richter Jun 09 '16 at 18:28
  • 5
    This answer ignores the entire concept of Cross-Site Scripting. – Jay Sullivan Jan 03 '17 at 17:11
19

I tend to follow Crockford's advice for eval(), and avoid it altogether. Even ways that appear to require it do not. For example, the setTimeout() allows you to pass a function rather than eval.

setTimeout(function() {
  alert('hi');
}, 1000);

Even if it's a trusted source, I don't use it, because the code returned by JSON might be garbled, which could at best do something wonky, at worst, expose something bad.

swilliams
  • 48,060
  • 27
  • 100
  • 130
  • 1
    How would a successful call to a web server yield a garbled result (bugs in the JSON-generating web server code notwithstanding)? – Tomalak Oct 13 '08 at 14:46
  • 2
    I think that bugs in the JSON formatter on the server side are certainly an issue. Does the response from the server depend on any kind of user submitted text? Then you gotta watch for XSS. – swilliams Oct 13 '08 at 15:06
  • 3
    If your webserver isn't authenticated via HTTPS, then you could suffer some sort of man-in-the-middle attack where another host intercepts the request and sends its own data. – Ben Combee Dec 21 '08 at 00:18
  • 11
    If someone can perform man-in-the-middle attack, he can easily inject anything to your scripts. – el.pescado - нет войне May 05 '10 at 17:11
  • 11
    You should not rely on your javascript code at all... You not rely on anything that runs on the client side... If someone does man-in-the-middle attack why would he mess with your json objects? He can serve a different webpage to you and different js files... – Calmarius Jul 01 '10 at 13:24
  • 6
    I personally dislike the argument "there are always other ways to do it." For example, you could also say there's always ways to avoid object oriented programming. That doesn't mean it's not a great option. If you understand eval and it's dangers, it can be a great tool to use in the right situations. – dallin May 13 '13 at 18:20
  • How would one write something like the "Tryit" editor on w3schools, Stack Snippets, etc. without `eval`? – Damian Yerrick May 11 '19 at 22:58
8

Eval is complementary to compilation which is used in templating the code. By templating I mean that you write a simplified template generator that generates useful template code which increases development speed.

I have written a framework, where developers don't use EVAL, but they use our framework and in turn that framework has to use EVAL to generate templates.

Performance of EVAL can be increased by using the following method; instead of executing the script, you must return a function.

var a = eval("3 + 5");

It should be organized as

var f = eval("(function(a,b) { return a + b; })");

var a = f(3,5);

Caching f will certainly improve the speed.

Also Chrome allows debugging of such functions very easily.

Regarding security, using eval or not will hardly make any difference,

  1. First of all, the browser invokes the entire script in a sandbox.
  2. Any code that is evil in EVAL, is evil in the browser itself. The attacker or anyone can easily inject a script node in DOM and do anything if he/she can eval anything. Not using EVAL will not make any difference.
  3. It is mostly poor server-side security that is harmful. Poor cookies validation or poor ACL implementation on the server causes most attacks.
  4. A recent Java vulnerability, etc. was there in Java's native code. JavaScript was and is designed to run in a sandbox, whereas applets were designed to run outside a sandbox with certificates, etc. that lead to vulnerabilities and many other things.
  5. Writing code for imitating a browser is not difficult. All you have to do is make a HTTP request to the server with your favourite user agent string. All testing tools mock browsers anyway; if an attacker want to harm you, EVAL is their last resort. They have many other ways to deal with your server-side security.
  6. The browser DOM does not have access to files and not a user name. In fact nothing on the machine that eval can give access to.

If your server-side security is solid enough for anyone to attack from anywhere, you should not worry about EVAL. As I mentioned, if EVAL would not exist, attackers have many tools to hack into your server irrespective of your browser's EVAL capability.

Eval is only good for generating some templates to do complex string processing based on something that is not used in advance. For example, I will prefer

"FirstName + ' ' + LastName"

As opposed to

"LastName + ' ' + FirstName"

As my display name, which can come from a database and which is not hardcoded.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Akash Kava
  • 39,066
  • 20
  • 121
  • 167
  • You can use function instead of eval - `function (first, last) { return last + ' ' + first }`. – Konrad Borowski Oct 15 '13 at 19:10
  • Names of columns come from database. – Akash Kava Oct 15 '13 at 19:49
  • 4
    The threat of `eval` is mostly *other users*. Let's say you have a settings page, and it lets you set how your name appears to others. Let's also say you weren't thinking very clearly when you wrote it, so your select box has options like ``. I open my dev tools, change the `value` of an option to `alert('PWNED!')`, select the changed option, and submit the form. Now, any time some other person can see my display name, that code runs. – cHao Jan 15 '14 at 15:05
  • 2
    @cHao, The one you are talking about is example of poor server side security, server should never accept a data that can be executed as code in anyone's browser. Once again, you have failed to understand concept of poor server side security. – Akash Kava Jun 09 '16 at 06:01
  • "If your server-side security is solid enough for anyone to attack from anywhere, you should not worry about EVAL." Exactly why you _should_ worry. No server is 100% secure. Password leaks, social engineering, bitter employees, security bugs. Not enough to ransack a system. But if I could update just one record in your database, I would go for the source table of your string processor. Potential XSS attack! That's how hackers work. They don't have the admin password. They find tiny weaknesses, none of which have any real impact. But combined, they may be just enough to do some real damage. – Ruud Helderman Jul 14 '19 at 18:34
  • @RuudHelderman The one who has access to one record in database has lot bigger security threat then the EVAL. – Akash Kava Aug 16 '22 at 05:23
  • @AkashKava In the past, having write access to the database was typically enough to take over an entire system. You would simply inject your own credentials into the users table. But not today. System administrators learned the hard way they need to restrict access to that sensitive table. The other 99 tables in that database are still wide open (non-admin users need that access). As a hacker, I would be patiently waiting for this one naive developer who will introduce some nice new table, say, CustomJavaScriptExpressionsForYourConvenience. That may _just_ be the entrance I need. – Ruud Helderman Aug 16 '22 at 08:20
  • @AkashKava In the movies, you see hackers completely taking over an entire system by exploiting a single weakness. That is not how things work in 2022. Hackers spend days/weeks/months gathering tiny vulnerabilities which __all together__ make it possible to take over a system. Every tiny bit helps them make progress. This 'relatively innocent' vulnerability may just be the missing piece of their puzzle. – Ruud Helderman Aug 16 '22 at 08:21
8

Bottom Line

If you created or sanitized the code you eval, it is never evil.

Slightly More Detailed

eval is evil if running on the server using input submitted by a client that was not created by the developer or that was not sanitized by the developer.

eval is not evil if running on the client, even if using unsanitized input crafted by the client.

Obviously you should always sanitize the input, as to have some control over what your code consumes.

Reasoning

The client can run any arbitrary code they want to, even if the developer did not code it; This is true not only for what is evaled, but the call to eval itself.

Steven Spungin
  • 27,002
  • 5
  • 88
  • 78
  • 1
    "eval is not evil if running on the client, even if using unsanitized input crafted by the client" This is not true. If person A crafts a script that gets `eval`'d on person B's client, they can do something like send person B's cookies to person A's remote server. – Deanveloper Oct 18 '21 at 17:02
  • Any person can run any code they choose on the client, regardless of what the developer codes. Even sanitation checks can be removed by browser plugins and manual changes. – Steven Spungin Oct 18 '21 at 19:12
  • 2
    That is simply not true. Otherwise XSS wouldn't be a security vulnerability. Really what I'm saying is that `eval` is as much of a security vulnerability as setting `innerHTML`. As long as you know what you're doing you're fine, but it may open the door to some attacks (ie cookie stealing) if you aren't careful. – Deanveloper Oct 22 '21 at 17:46
6

When debugging in Chrome (v28.0.1500.72), I found that variables are not bound to closures if they are not used in a nested function that produces the closure. I guess, that's an optimization of the JavaScript engine.

BUT: when eval() is used inside a function that causes a closure, ALL the variables of outer functions are bound to the closure, even if they are not used at all. If someone has the time to test if memory leaks can be produced by that, please leave me a comment below.

Here's my test code:

(function () {
    var eval = function (arg) {
    };

    function evalTest() {
        var used = "used";
        var unused = "not used";

        (function () {
            used.toString();   // Variable "unused" is visible in debugger
            eval("1");
        })();
    }

    evalTest();
})();

(function () {
    var eval = function (arg) {
    };

    function evalTest() {
        var used = "used";
        var unused = "not used";

        (function () {
            used.toString();   // Variable "unused" is NOT visible in debugger
            var noval = eval;
            noval("1");
        })();
    }

    evalTest();
})();

(function () {
    var noval = function (arg) {
    };

    function evalTest() {
        var used = "used";
        var unused = "not used";

        (function () {
            used.toString();    // Variable "unused" is NOT visible in debugger
            noval("1");
        })();
    }

    evalTest();
})();

What I like to point out here is, that eval() must not necessarily refer to the native eval() function. It all depends on the name of the function. So when calling the native eval() with an alias name (say var noval = eval; and then in an inner function noval(expression);) then the evaluation of expression may fail when it refers to variables that should be part of the closure, but is actually not.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Benjamin
  • 1,165
  • 7
  • 19
4

I saw people advocate to not use eval, because is evil, but I saw the same people use Function and setTimeout dynamically, so they use eval under the hoods :D

BTW, if your sandbox is not sure enough (for example, if you're working on a site that allow code injection) eval is the last of your problems. The basic rule of security is that all input is evil, but in case of JavaScript even JavaScript itself could be evil, because in JavaScript you can overwrite any function and you just can't be sure you're using the real one, so, if a malicious code start before you, you can't trust any JavaScript built-in function :D

Now the epilogue to this post is:

If you REALLY need it (80% of the time eval is NOT needed) and you're sure of what you' re doing, just use eval (or better Function ;) ), closures and OOP cover the 80/90% of the case where eval can be replaced using another kind of logic, the rest is dynamically generated code (for example, if you're writing an interpreter) and as you already said evaluating JSON (here you can use the Crockford safe evaluation ;) )

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
kentaromiura
  • 6,459
  • 2
  • 21
  • 15
  • And [as pointed out by Crockford himself](https://github.com/douglascrockford/JSON-js), current web browsers have a built-in function [JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse). – Ruud Helderman Jul 14 '19 at 15:40
2

The only instance when you should be using eval() is when you need to run dynamic JS on the fly. I'm talking about JS that you download asynchronously from the server...

...And 9 times of 10 you could easily avoid doing that by refactoring.

Oli
  • 235,628
  • 64
  • 220
  • 299
  • Nowadays, there are other (and better) ways of loading JavaScript asynchronously from the server: https://w3bits.com/async-javascript – Ruud Helderman Jul 14 '19 at 15:31
2

On the server side eval is useful when dealing with external scripts such as sql or influxdb or mongo. Where custom validation at runtime can be made without re-deploying your services.

For example an achievement service with following metadata

{
  "568ff113-abcd-f123-84c5-871fe2007cf0": {
    "msg_enum": "quest/registration",
    "timely": "all_times",
    "scope": [
      "quest/daily-active"
    ],
    "query": "`SELECT COUNT(point) AS valid from \"${userId}/dump/quest/daily-active\" LIMIT 1`",
    "validator": "valid > 0",
    "reward_external": "ewallet",
    "reward_external_payload": "`{\"token\": \"${token}\", \"userId\": \"${userId}\", \"amountIn\": 1, \"conversionType\": \"quest/registration:silver\", \"exchangeProvider\":\"provider/achievement\",\"exchangeType\":\"payment/quest/registration\"}`"
  },
  "efdfb506-1234-abcd-9d4a-7d624c564332": {
    "msg_enum": "quest/daily-active",
    "timely": "daily",
    "scope": [
      "quest/daily-active"
    ],
    "query": "`SELECT COUNT(point) AS valid from \"${userId}/dump/quest/daily-active\" WHERE time >= '${today}' ${ENV.DAILY_OFFSET} LIMIT 1`",
    "validator": "valid > 0",
    "reward_external": "ewallet",
    "reward_external_payload": "`{\"token\": \"${token}\", \"userId\": \"${userId}\", \"amountIn\": 1, \"conversionType\": \"quest/daily-active:silver\", \"exchangeProvider\":\"provider/achievement\",\"exchangeType\":\"payment/quest/daily-active\"}`"
  }
}

Which then allow,

  • Direct injection of object/values thru literal string in a json, useful for templating texts

  • Can be use as a comparator, say we make rules how to validate quest or events in CMS

Con of this:

  • Can be errors in the code and break up things in the service, if not fully tested.

  • If a hacker can write script on your system, then you are pretty much screwed.

  • One way to validate your script is keep the hash of your scripts somewhere safe, so you can check them before running.

MichaelC
  • 51
  • 4
2

Eval isn't evil, just misused.

If you created the code going into it or can trust it, it's alright. People keep talking about how user input doesn't matter with eval. Well sort of~

If there is user input that goes to the server, then comes back to the client, and that code is being used in eval without being sanitized. Congrats, you've opened pandora's box for user data to be sent to whoever.

Depending on where the eval is, many websites use SPAs, and eval could make it easier for the user to access application internals that otherwise wouldn't have been easy. Now they can make a bogus browser extension that can tape into that eval and steal data again.

Just gotta figure what's the point of you using the eval. Generating code isn't really ideal when you could simply make methods to do that sort of thing, use objects, or the like.

Now a nice example of using eval. Your server is reading the swagger file that you have created. Many of the URL params are created in the format {myParam}. So you'd like to read the URLs and then convert them to template strings without having to do complex replacements because you have many endpoints. So you may do something like this. Note this is a very simple example.

const params = { id: 5 };

const route = '/api/user/{id}';
route.replace(/{/g, '${params.');

// use eval(route); to do something

jemiloii
  • 24,594
  • 7
  • 54
  • 83
1

As far as client script goes, I think the issue of security is a moot point. Everything loaded into the browser is subject to manipulation and should be treated as such. There is zero risk in using an eval() statement when there are much easier ways to execute JavaScript code and/or manipulate objects in the DOM, such as the URL bar in your browser.

javascript:alert("hello");

If someone wants to manipulate their DOM, I say swing away. Security to prevent any type of attack should always be the responsibility of the server application, period.

From a pragmatic standpoint, there's no benefit to using an eval() in a situation where things can be done otherwise. However, there are specific cases where an eval SHOULD be used. When so, it can definitely be done without any risk of blowing up the page.

<html>
    <body>
        <textarea id="output"></textarea><br/>
        <input type="text" id="input" />
        <button id="button" onclick="execute()">eval</button>

        <script type="text/javascript">
            var execute = function(){
                var inputEl = document.getElementById('input');
                var toEval = inputEl.value;
                var outputEl = document.getElementById('output');
                var output = "";

                try {
                    output = eval(toEval);
                }
                catch(err){
                    for(var key in err){
                        output += key + ": " + err[key] + "\r\n";
                    }
                }
                outputEl.value = output;
            }
        </script>
    <body>
</html>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 6
    Re "There is zero risk in using an eval() statement when there are much easier ways to execute javascript and/or manipulate objects in the DOM". Code injection is a problem when one user can enter code that is then run in another user's browser. Browser consoles do not by themselves allow one user to run code in another users browser so they are irrelevant when deciding whether it is worth protecting against code injection. – Mike Samuel Aug 03 '12 at 22:30
  • Isn't `` required, even if empty? – Peter Mortensen Jan 13 '17 at 22:57
  • 2
    This answer completely ignores the risks of [XSS](https://en.wikipedia.org/wiki/Cross-site_scripting). – Ruud Helderman Jul 14 '19 at 14:56
1

eval is rarely the right choice. While there may be numerous instances where you can accomplish what you need to accomplish by concatenating a script together and running it on the fly, you typically have much more powerful and maintainable techniques at your disposal: associative-array notation (obj["prop"] is the same as obj.prop), closures, object-oriented techniques, functional techniques - use them instead.

yfeldblum
  • 65,165
  • 12
  • 129
  • 169
1

Since no one has mentioned it yet, let me add that eval is super useful for Webassembly-Javascript interop. While it's certainly ideal to have pre-made scripts included in your page that your WASM code can invoke directly, sometimes it's not practicable and you need to pass in dynamic Javascript from a Webassembly language like C# to really accomplish what you need to do.

It's also safe in this scenario because you have complete control over what gets passed in. Well, I should say, it's no less safe than composing SQL statements using C#, which is to say it needs to be done carefully (properly escaping strings, etc.) whenever user-supplied data is used to generate the script. But with that caveat it has a clear place in interop situations and is far from "evil".

Emperor Eto
  • 2,456
  • 2
  • 18
  • 32
0

My example of using eval: import.

How it's usually done.

var components = require('components');
var Button = components.Button;
var ComboBox = components.ComboBox;
var CheckBox = components.CheckBox;
...
// That quickly gets very boring

But with the help of eval and a little helper function it gets a much better look:

var components = require('components');
eval(importable('components', 'Button', 'ComboBox', 'CheckBox', ...));

importable might look like (this version doesn't support importing concrete members).

function importable(path) {
    var name;
    var pkg = eval(path);
    var result = '\n';

    for (name in pkg) {
        result += 'if (name !== undefined) throw "import error: name already exists";\n'.replace(/name/g, name);
    }

    for (name in pkg) {
        result += 'var name = path.name;\n'.replace(/name/g, name).replace('path', path);
    }
    return result;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Yaroslav
  • 4,543
  • 5
  • 26
  • 36
  • 2
    +1 for the idea, but you have a bug here: `.replace(/name/g, name).replace('path', path)`. If `name` contains the string `"path"` then you could get surprises. – wberry Mar 25 '14 at 15:36
  • 1
    Declaring one variable for each property of `components` is a possible code smell; refactoring your code might eliminate the 'problem' altogether. Your current solution is just syntactic sugar. If you insist on doing that, then I would recommend writing your own preprocessor, to be executed prior to deployment. That should keep `eval` away from production code. – Ruud Helderman Jul 14 '19 at 14:40
0

It's okay to use it if you have complete control over the code that's passed to the eval function.

John Topley
  • 113,588
  • 46
  • 195
  • 237
  • 2
    If you have complete control over what you're passing to `eval`, then the big question becomes, when does it make sense for that to be a string rather than real JS? – cHao Jan 15 '14 at 13:59
  • @cHao For example, if you have a large Game-Application (5-10MB Javascript), its better to build first a simple fast-loading AJAX-Preloader (1kb), which loads the large Main-Script, while displaying a Loading-Bar or something similar. After downloading you can use "eval(source)" or better "new Function(source)" to run the loaded Game-Application-Script. That way the user can see visually that the Application needs time to download until the game can start. Without that the user has to wait for the whole Application to load without any visually feedback. – SammieFox Apr 11 '17 at 18:08
  • @SammieFox There are other (and better) ways of doing this, most notably ` – Ruud Helderman Jul 14 '19 at 15:17
  • The answer is dangerous advice; too many developers have a false sense of being in control. The advice _does_ make some sense for software that is no longer actively maintained. But such software should be considered dead. – Ruud Helderman Jul 14 '19 at 15:27
0

There is no reason not to use eval() as long as you can be sure that the source of the code comes from you or the actual user. Even though he can manipulate what gets sent into the eval() function, that's not a security problem, because he is able to manipulate the source code of the web site and could therefore change the JavaScript code itself.

So... when to not use eval()? Eval() should only not be used when there is a chance that a third party could change it. Like intercepting the connection between the client and your server (but if that is a problem use HTTPS). You shouldn't eval() for parsing code that is written by others like in a forum.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Georg Schölly
  • 124,188
  • 49
  • 220
  • 267
  • Re "There is no reason not to use eval() as long as you can be sure that the source of the code comes from you or the actual user." This assumes that there is a single user. That premise is not stated in the OP. When there are multiple users, careless `eval` of a string composed from content from one user can allow that user to execute code in the other user's browser. – Mike Samuel Aug 03 '12 at 22:33
  • @MikeSamuel, eval can execute code in other user's browser, I havent heard this, have you tried this? This never happened in history of browsing, can you show us an example? – Akash Kava Apr 19 '13 at 10:20
  • @AkashKava, A string can originate with one user-agent, be stored in a database, and then served to another browser which `eval`s it. It happens all the time. – Mike Samuel Apr 19 '13 at 15:10
  • @MikeSamuel database? where? who serves wrong string? isnt it database on server side to blame? first of all EVAL is not to be blamed for poorly written server side code. Use jsfiddle and show the world a real world example where it can cause harm. – Akash Kava Apr 19 '13 at 16:10
  • 2
    @AkashKava, I don't understand your question. We aren't talking about a specific application, but reasons not to use `eval`. How is it useful to blame the server? If anyone should be blamed, it should be the attacker. Regardless of blame, a client that is not vulnerable to XSS despite bugs in the server is better than a client that is vulnerable, all else being equal. – Mike Samuel Apr 19 '13 at 16:18
  • @AkashKava You might need `eval` to _make_ jsfiddle. – Damian Yerrick May 11 '19 at 23:01
  • "There is no reason..." Incorrect. This answer ignores performance and maintainability. – Ruud Helderman Jul 13 '19 at 21:42
0

If it's really needed eval is not evil. But 99.9% of the uses of eval that I stumble across are not needed (not including setTimeout stuff).

For me the evil is not a performance or even a security issue (well, indirectly it's both). All such unnecessary uses of eval add to a maintenance hell. Refactoring tools are thrown off. Searching for code is hard. Unanticipated effects of those evals are legion.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
PEZ
  • 16,821
  • 7
  • 45
  • 66
0

Code generation. I recently wrote a library called Hyperbars which bridges the gap between virtual-dom and handlebars. It does this by parsing a handlebars template and converting it to hyperscript. The hyperscript is generated as a string first and before returning it, eval() it to turn it into executable code. I have found eval() in this particular situation the exact opposite of evil.

Basically from

<div>
    {{#each names}}
        <span>{{this}}</span>
    {{/each}}
</div>

To this

(function (state) {
    var Runtime = Hyperbars.Runtime;
    var context = state;
    return h('div', {}, [Runtime.each(context['names'], context, function (context, parent, options) {
        return [h('span', {}, [options['@index'], context])]
    })])
}.bind({}))

The performance of eval() isn't an issue in a situation like this too because you only need to interpret the generated string once and then reuse the executable output many times over.

You can see how the code generation was achieved if you're curious here.

Wikened
  • 75
  • 9
  • "The hyperscript is generated as a string first (...)" Makes more sense to do all code generation in the build phase, write the resulting hyperscript code to a separate executable (.js) file, then deploy that file to test and production. I love the way you use code generation. It's just that `eval` is a hint that some responsibility that belongs in compile time, has moved into runtime. – Ruud Helderman Jul 14 '19 at 14:11
0

I think any cases of eval being justified would be rare. You're more likely to use it thinking that it's justified than you are to use it when it's actually justified.

The security issues are the most well known. But also be aware that JavaScript uses JIT compilation and this works very poorly with eval. Eval is somewhat like a blackbox to the compiler, and JavaScript needs to be able to predict code ahead of time (to some extent) in order to safely and correctly apply performance optimisations and scoping. In some cases, the performance impact can even affect other code outside eval.

If you want to know more: https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20%26%20closures/ch2.md#eval

Andre OBrien
  • 160
  • 1
  • 11
-1

When is JavaScript's eval() not evil?

I'm always trying to discourage from using eval. Almost always, a more clean and maintainable solution is available. Eval is not needed even for JSON parsing. Eval adds to maintenance hell. Not without reason, it is frowned upon by masters like Douglas Crockford.

But I found one example where it should be used:

When you need to pass the expression.

For example, I have a function that constructs a general google.maps.ImageMapType object for me, but I need to tell it the recipe, how should it construct the tile URL from the zoom and coord parameters:

my_func({
    name: "OSM",
    tileURLexpr: '"http://tile.openstreetmap.org/"+b+"/"+a.x+"/"+a.y+".png"',
    ...
});

function my_func(opts)
{
    return new google.maps.ImageMapType({
        getTileUrl: function (coord, zoom) {
            var b = zoom;
            var a = coord;
            return eval(opts.tileURLexpr);
        },
        ....
    });
}
Community
  • 1
  • 1
Tomas
  • 57,621
  • 49
  • 238
  • 373
  • 3
    This looks like it could be refactored so that eval() isn't necessary - tileURLexpr is just a template so some judicious use of replace() would do the job. Still, it does remind me of an example I had in mind when I submitted the question, which was to do with allowing a user to specify a mathematical formula to be evaluated, similar to spreadsheet functionality. Of course I didn't mention that at the time because I didn't want to influence the answers! – Richard Turner May 11 '12 at 13:10
  • 9
    `tileURL: function (zoom, coord) { return 'http://tile.openstreetmap.org/' + b + '/' + a.x + '/' + a.y + '.png'; },` – Casey Chu Oct 30 '13 at 09:32
-1

Eval is useful for code generation when you don't have macros.

For (a stupid) example, if you're writing a Brainfuck compiler, you'll probably want to construct a function that performs the sequence of instructions as a string, and eval it to return a function.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Erik Haliewicz
  • 126
  • 1
  • 4
  • Either you write a compiler (which saves rather than executes the code being generated) or you write an interpreter (where each instruction has a pre-compiled implementation). Neither is a use case for `eval`. – Ruud Helderman Jul 14 '19 at 12:31
  • 1
    If you generated javascript code and wanted to immediately execute it (let's say for performance benefits over direct interpretation), that would be a use case for eval. – Erik Haliewicz Jul 16 '19 at 22:28
  • Good point; I saw an example in [this article about Blockly](https://developers.google.com/blockly/guides/app-integration/running-javascript). I'm shocked Google recommends `eval`, when the alternative ([Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function)) is both faster ([as explained in MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Do_not_ever_use_eval!)) and more reliable (prevents unpredictable bugs by better isolation between the generated code and other 'supportive' code on the same webpage). – Ruud Helderman Jul 17 '19 at 12:03
-1

Only during testing, if possible. Also note that eval() is much slower than other specialized JSON etc. evaluators.

Eric Wendelin
  • 43,147
  • 9
  • 68
  • 92
-1

My belief is that eval is a very powerful function for client-side web applications and safe... As safe as JavaScript, which are not. :-) The security issues are essentially a server-side problem because, now, with tool like Firebug, you can attack any JavaScript application.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 1
    The use of `eval` needs to be secured against XSS attacks, which is not always easy to get right. – Benjamin Sep 19 '16 at 09:52
-1

While there may be numerous instances where you can accomplish what you need to accomplish by concatenating a script together and running it on the fly, you typically have much more powerful and maintainable techniques at your disposal. eval is rarely the right choice.: associative-array notation (obj["prop"] is the same as obj.prop), closures, object-oriented techniques, functional techniques - use them instead.

Mouzam Ali
  • 27
  • 3
-5

When you parse a JSON structure with a parse function (for example, jQuery.parseJSON), it expects a perfect structure of the JSON file (each property name is in double quotes). However, JavaScript is more flexible. Therefore, you can use eval() to avoid it.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
vitmalina
  • 1,829
  • 1
  • 14
  • 7
  • 4
    Don't blindly use `eval`, esp. when getting JSON data from a third-party source. See [JSON.Stringify without quotes on properties?](http://stackoverflow.com/questions/11233498/json-stringify-without-quotes-on-properties) for the correct approach to parse "JSON without quoted key names". – Rob W Jul 20 '12 at 20:58
  • 2
    If it doesn't use double quotes around property names, it might be a string representation of an object literal, but it is not [JSON](http://json.org/). JSON defines the property names as a `string` and defines a `string` as _a sequence of zero or more Unicode characters, wrapped in double quotes, using backslash escapes._ – Useless Code Mar 19 '13 at 13:34
  • See article by Nikolas Zakas - "eval() isn’t evil, just misunderstood" http://www.nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunderstood/ – vitmalina Jul 12 '13 at 05:16
  • @vitmalina From Zakas' article: "This can be dangerous if you’re taking user input and running it through eval(). However, if your input isn’t from the user, is there any real danger?" That's exactly the problem. Once your code grows beyond 'hello world' proportions, it quickly becomes impossible to prove you are not leaking user input into `eval`. In any serious multi-tenant web application, with dozens of developers working on the same code base, this is unacceptable. – Ruud Helderman Jul 13 '19 at 23:14