Why is eval still in use when it is a big concern regarding security?

MDN documentation says:

Never use eval()!

Using direct eval() suffers from multiple problems:

  • eval() executes the code it's passed with the privileges of the caller. If you run eval() with a string that could be affected by a malicious party, you may end up running malicious code on the user's machine with the permissions of your webpage / extension. More importantly, allowing third-party code to access the scope in which eval() was invoked (if it's a direct eval) can lead to possible attacks that reads or changes local variables.
  • eval() is slower than the alternatives, since it has to invoke the JavaScript interpreter, while many other constructs are optimized by modern JS engines.
  • Modern JavaScript interpreters convert JavaScript to machine code. This means that any concept of variable naming gets obliterated. Thus, any use of eval() will force the browser to do long expensive variable name lookups to figure out where the variable exists in the machine code and set its value. Additionally, new things can be introduced to that variable through eval(), such as changing the type of that variable, forcing the browser to re-evaluate all of the generated machine code to compensate.
  • Minifiers give up on any minification if the scope is transitively depended on by eval(), because otherwise eval() cannot read the correct variable at runtime.

MDN documentation is right in regard to suggesting a very sensible default. You are unlikely to ever need to use eval() when developing applications in JavaScript. However, eval() is handy when writing tooling in JavaScript. Whenever you do so, you must acknowledge and account for the security concerns surrounding the usage of eval().

If you make an app that executes JavaScript written by the app's user (a spreadsheet app, for example), you need something like eval to run the code.

Named-eval was specifically supported so we can evaluate multiple user-provided JS source strings, and know which is which in stack traces (as the strings have no URLs). I made a browser based REPL back in the day which would have been impossible without these features.