Skip to content

Python eval() Function

How to use Python's eval() function to dynamically evaluate expressions, its parameters (expression, globals, locals), return values, and security risks with mitigation strategies.

The eval() method parses the expression passed to this method and runs python expression (code) within the program.

Syntax

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

eval() Parameters

Python eval() function parameters:

Parameter Condition Description
expression Required A String, that will be evaluated as Python code
globals Optional A dictionary containing global parameters
locals Optional A dictionary containing local parameters

eval() Return Value

Python eval() function returns the result evaluated from the expression.

Examples

Example 1: evaluating an arithmetic expression with eval() function

result = eval('1 + 2')
print(result)  # Output:  3

output

3

Example 2: evaluating a complex expression involving a function call with eval() function

result = eval('sum([1,  2,  3,  4])')
print(result)  # Output:  10

output

10

Example 3: evaluating a boolean expression with eval() function

result = eval('True and False')
print(result)  # Output: False

output

False

Example 4: using eval() with custom global and local namespaces

def square(number):
    return number * number

global_vars = {"square": square}
result = eval("square(5)", global_vars)
print(result)  # Output:  25

output

25

Security issues of using eval() function and possible mitigations

Security issues of eval() function

The Python eval() function can expose you to some security risks.

Consider a situation where you are using a Unix system (macOS, Linux, etc.) and you have imported the os module. The os module provides a portable way to use operating system functionalities like reading or writing to a file.

If you allow users to input a value using eval(input()), the user may issue commands to change file or even delete all the files using the command: os.system('rm -rf *').

If you are using eval(input()) in your code, it is a good idea to check which variables and functions the user can use. You can see which variables and methods are available using dir() function.

Mitigations of using eval() function

Frequently, not all methods and variables that are available within the scope of eval() are required or even pose potential security threats. Therefore, it is often beneficial to limit the scope of these methods and variables for safety purposes.

To achieve this, you can provide the eval() function with optional globals and locals parameters, which are dictionaries that define the global and local namespaces for the evaluated expression.

1. When both globals and locals parameters omitted

If both parameters are omitted (as in our earlier examples), the expression is executed in the current scope. You can check the available variables and methods using following code:

print(eval('dir()')

2. Passing globals parameter and locals parameter is omitted

When using eval() in Python, you can specify the global and local namespaces through the globals and locals parameters. If the locals parameter is not provided, it defaults to the globals dictionary, meaning that the global namespace will be used for both global and local variables within the evaluated expression.

For example, you can pass empty dictionary as globals parameter:

from math import *
print(eval('dir()', {}))

print(eval('sqrt(25)', {}))

output

['__builtins__']
Traceback (most recent call last):
  File "main.py", line 5, in <module>
    print(eval('sqrt(25)', {}))
  File "<string>", line 1, in <module>
NameError: name 'sqrt' is not defined

For example, you can make certain methods available (the expression can only use the sqrt() and the pow() methods along with __builtins__):

from math import *
print(eval('dir()', {'sqrt': sqrt, 'pow': pow}))

output

['__builtins__', 'pow', 'sqrt']

It is also possible to change the name of the method available for the expression as you want:

from math import *
names = {'square_root': sqrt, 'power': pow}
print(eval('dir()', names))

print(eval('square_root(9)', names))

output

['__builtins__', 'power', 'square_root']
3.0

You can restrict the use of __builtins__ in the expression as follows:

eval(expression, {'__builtins__': None})

3. Passing both globals and locals dictionary

To expose specific functions and variables for use within the eval() function, you can pass a dictionary to the locals parameter. This allows you to control which names are considered local within the evaluated expression.

For example, in the following program, expressions evaluated by eval() function can have sqrt() method and variable a only. All other methods and variables are unavailable.

from math import *

a = 144
result = eval('sqrt(a)', {'__builtins__': None}, {'a': a, 'sqrt': sqrt})
print(result) # Output: 12.0

output

12.0
Navigation