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: 3output
3Example 2: evaluating a complex expression involving a function call with eval() function
result = eval('sum([1, 2, 3, 4])')
print(result) # Output: 10output
10Example 3: evaluating a boolean expression with eval() function
result = eval('True and False')
print(result) # Output: Falseoutput
FalseExample 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: 25output
25Security 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 definedFor 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.0You 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.0output
12.0