Evaluation – Why Eval-Like Features Are Considered Evil

evaluationmalicious-code

Most modern languages (which are somehow interpreted) have some kind of eval function. Such a function executes arbitrary language code, most of the time passed as the main argument as a string (different languages may add more features to the eval function).

I understand users should not be allowed to execute this function (edit i.e. take directly or indirectly arbitrary input from an arbitrary user to be passed to eval), especially with server-side software, since they could force the process to execute malicious code. In that way, tutorials and communities tell us to not use eval. However, there are many times where eval is useful and used:

  • Custom access rules to software elements (IIRC OpenERP has an object ir.rule which can use dynamic python code).
  • Custom calculations and/or criteria (OpenERP has fields like that to allow custom code calculations).
  • OpenERP report parsers (yes I know I'm freaking you out with OpenERP stuff… but it is the main example I have).
  • Coding spell effects in some RPG games.

So they have a good use, as long as they are used properly. The main advantage is that the feature allows admins to write custom code without having to create more files and include them (although most frameworks using eval features have also a way to specify a file, module, package, … to read from).

However, eval is evil in the popular culture. Stuff like breaking into your system comes to mind.

However, there are other functions which could be harmful if somehow accessed by users: unlink, read, write (file semantics), memory allocation and pointer arithmetic, database model access (even if not considering SQL-injectable cases).

So, basically, most of the time when any code is not written properly or not watched properly (resources, users, environments, …), the code is evil and can lead even to economic impact.

But there's something special with eval functions (regardless of the language).

Question: Is there any historical fact for this fear becoming part of the popular culture, instead of giving the same attention to the other possibly dangerous features?

Best Answer

An eval function by itself is not evil, and there is a subtle point that I do not believe you are making:

Allowing a program to execute arbitrary user input is bad

I have written code that used an eval type of function and it was secure: the program and parameters were hard-coded. Sometimes, there is no language or library feature to do what the program needs and running a shell command is the short path. "I have to finish coding this in a few hours, but writing Java/.NET/PHP/whatever code will take two days. Or I can eval it in five minutes."

Once you allow users to execute anything they want, even if locked down by user privilege or behind a "secure" screen, you create attack vectors. Every week, some random CMS, blogging software, etc. has a security hole patched where an attacker can exploit a hole like this. You are relying on the entire software stack to protect access to a function that can be used to rm -rf / or something else catastrophic (note: that command is unlikely to succeed, but will fail after causing a bit of damage).

Is there any historical fact for this fear becoming part of the popular culture, instead of putting the same attention to the other possibly dangerous features?

Yes, there is a historical precedent. Due to the numerous bugs that have been fixed over the years in various software that allow remote attackers to execute arbitrary code, the idea of eval has mostly fallen out of favor. Modern languages and libraries have rich sets of functionality that make eval less important, and this is no accident. It both makes functions easier to use and reduces the risk of an exploit.

There has been much attention paid to many potentially insecure features in popular languages. Whether one receives more attention is primarily a matter of opinion, but the eval features certainly have a provable security problem that is easy to understand. For one, they allow executing operating system commands including shell built-ins and external programs that are standard (e.g. rm or del). Two, combined with other exploits, an attacker may be able to upload their own executable or shell script then execute it via your software, opening the door for almost anything to happen (none of it good).

This is a difficult problem. Software is complex, and a software stack (e.g. LAMP) is multiple pieces of software that interact with each other in complex ways. Be careful how you use language features such as this, and never allow users to execute arbitrary commands.