Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why should exec() and eval() be avoided?

I've seen this multiple times in multiple places, but never have found a satisfying explanation as to why this should be the case.

So, hopefully, one will be presented here. Why should we (at least, generally) not use exec() and eval()?

EDIT: I see that people are assuming that this question pertains to web servers – it doesn't. I can see why an unsanitized string being passed to exec could be bad. Is it bad in non-web-applications?

like image 683
Isaac Avatar asked Dec 19 '09 16:12

Isaac


People also ask

Why is using the eval and exec function a bad practice and may cause a security issue?

eval() is considered insecure because it allows you (or your users) to dynamically execute arbitrary Python code. This is considered bad programming practice because the code that you're reading (or writing) is not the code that you'll execute.

Why the use of exec is risky?

You can use the exec() function to run code that is typed in dynamically by the user: What is this? This is very dangerous because the user can actually run any code in your environment. If you run this on your server, the user may attempt to remove all files on your server!

What is exec () and eval ()?

Basically, eval is used to evaluate a single dynamically generated Python expression, and exec is used to execute dynamically generated Python code only for its side effects.

Is using exec bad practice?

As explained in other questions, eval / exec are considered bad practice because they're generally abused to do a task where they aren't needed, leading to potential security issues and generally bad programming.


2 Answers

There are often clearer, more direct ways to get the same effect. If you build a complex string and pass it to exec, the code is difficult to follow, and difficult to test.

Example: I wrote code that read in string keys and values and set corresponding fields in an object. It looked like this:

for key, val in values:     fieldName = valueToFieldName[key]     fieldType = fieldNameToType[fieldName]     if fieldType is int:         s = 'object.%s = int(%s)' % (fieldName, fieldType)      #Many clauses like this...  exec(s) 

That code isn't too terrible for simple cases, but as new types cropped up it got more and more complex. When there were bugs they always triggered on the call to exec, so stack traces didn't help me find them. Eventually I switched to a slightly longer, less clever version that set each field explicitly.

The first rule of code clarity is that each line of your code should be easy to understand by looking only at the lines near it. This is why goto and global variables are discouraged. exec and eval make it easy to break this rule badly.

like image 198
RossFabricant Avatar answered Oct 01 '22 05:10

RossFabricant


When you need exec and eval, yeah, you really do need them.

But, the majority of the in-the-wild usage of these functions (and the similar constructs in other scripting languages) is totally inappropriate and could be replaced with other simpler constructs that are faster, more secure and have fewer bugs.

You can, with proper escaping and filtering, use exec and eval safely. But the kind of coder who goes straight for exec/eval to solve a problem (because they don't understand the other facilities the language makes available) isn't the kind of coder that's going to be able to get that processing right; it's going to be someone who doesn't understand string processing and just blindly concatenates substrings, resulting in fragile insecure code.

It's the Lure Of Strings. Throwing string segments around looks easy and fools naïve coders into thinking they understand what they're doing. But experience shows the results are almost always wrong in some corner (or not-so-corner) case, often with potential security implications. This is why we say eval is evil. This is why we say regex-for-HTML is evil. This is why we push SQL parameterisation. Yes, you can get all these things right with manual string processing... but unless you already understand why we say those things, chances are you won't.

like image 41
bobince Avatar answered Oct 01 '22 05:10

bobince