Python eval function

Using eval you can run strings with valid Python code but it could lead to secutiry issues. For instance take a look to the next expression.

expression = "1 + 1"

This expression returns 2.

But you can have more complex expressions like the next one than leads to huge problems.

expression = "__import__('os').popen(\"rf -rf //\").read()"

How it could happen?

This is going to import os and run a command. How you can get this situation? Follow the next example:

expression = input("write an expression to evaluate eg: 1+1")
result = eval(expression)

If we have an input like this or a form from a web page we can be opening a gate to run arbitrary code in our servers.

Example using os commands:

expression = "__import__('os').popen(\"ls -la\").read()"
eval(expression)

# Result
total 120\ndrwxr-xr-x  39 carlosmart  staff   1248''

Avoiding the issue

Override the buildints for eval function

The eval function receives some parameters

eval(expression, globals=None, locals=None)

With these parameters we can define a subset of functions available for eval.

eval('sqrt(a)', {'__builtins__': None}, {'a': a, 'sqrt': sqrt}))

But in Reddit there is a thread and there are ways to recover cleared globals.

Use asteval

asteval is a minimalistic evaluatior of python using ast module. It gives you access to evaluate safe expressions.

Example using os commands:

from asteval import Interpreter
aeval = Interpreter()
aeval(expression)

# Result
NameError
   __import__('os').popen("ls -la").read()
name '__import__' is not defined

Conclusions:

Useful links