Making eval() safe

Python eval function comes with the facility of explicitly passing a list of functions or variables that it can access. We need to pass it as an argument in the form of a dictionary.

Python3




from math import *
 
def secret_function():
    return "Secret key is 1234"
 
def function_creator():
 
    # expression to be evaluated
    expr = input("Enter the function(in terms of x):")
 
    # variable used in expression
    x = int(input("Enter the value of x:"))
 
    # passing variable x in safe dictionary
    safe_dict['x'] = x
 
    # evaluating expression
    y = eval(expr, {}, safe_dict)
 
    # printing evaluated result
    print("y = {}".format(y))
 
 
if __name__ == "__main__":
 
    # list of safe methods
    safe_list = ['acos', 'asin', 'atan', 'atan2', 'ceil', 'cos',
                 'cosh', 'degrees', 'e', 'exp', 'fabs', 'floor',
                 'fmod', 'frexp', 'hypot', 'ldexp', 'log', 'log10',
                 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt',
                 'tan', 'tanh']
 
    # creating a dictionary of safe methods
    safe_dict = {}
    for safe_key in safe_list:
        safe_dict[safe_key] = locals().get(safe_key)
 
    function_creator()


Now if we try to run the above programs like:

Enter the function(in terms of x):secret_function()
Enter the value of x:0

We get the output:

NameError: name 'secret_function' is not defined

Let us analyze the above code step by step:

  • First, we create a list of methods we want to allow as safe_list.
  • Next, we create a dictionary of safe methods. In this dictionary, keys are the method names and values are their local namespaces.
safe_dict = {}
for safe_key in safe_list:
    safe_dict[safe_key] = locals().get(safe_key)
  • locals() is a built-in method that returns a dictionary that maps all the methods and variables in the local scope with their namespaces.
safe_dict['x'] = x

Here, we add the local variable x to the safe_dict too. No local variable other than x will get identified by the eval function.

  • eval accepts dictionaries of local as well as global variables as arguments. So, in order to ensure that none of the built-in methods is available to eval expression, we pass another dictionary along with safe_dict as well, as shown below:
y = eval(expr, {}, safe_dict)

So, in this way, we have made our eval function safe from any possible hacks!



eval in Python

Python eval() function parse the expression argument and evaluate it as a Python expression and runs Python expression (code) within the program.

Similar Reads

Python eval() Function Syntax

Syntax: eval(expression, globals=None, locals=None) Parameters: expression: String is parsed and evaluated as a Python expression globals [optional]: Dictionary to specify the available global methods and variables. locals [optional]: Another dictionary to specify the available local methods and variables. Return: Returns output of the expression....

eval() Function in Python Example

Python3 print(eval('1+2')) print(eval("sum([1, 2, 3, 4])"))...

Evaluating Expressions using Python’s eval()

...

Vulnerability issues with Python eval() Function

...

Making eval() safe

Evaluate Mathematical Expressions in Python...