Dynamic code execution with `exec` and `eval`
- eval(expression[, globals=None[, locals=None]])
- exec(object, globals)
- exec(object, globals, locals)
|The expression code as a string, or a |
|The statement code as a string, or a |
|The dictionary to use for global variables. If locals is not specified, this is also used for locals. If omitted, the |
|A mapping object that is used for local variables. If omitted, the one passed for |
locals (i.e. they refer to the same object), the code is executed as if it is on the module level. If
locals are distinct objects, the code is executed as if it were in a class body.
globals object is passed in, but doesn't specify
__builtins__ key, then Python built-in functions and names are automatically added to the global scope. To suppress the availability of functions such as
isinstance in the executed scope, let
globals have the key
__builtins__ mapped to value
None. However, this is not a security feature.
The Python 2 -specific syntax shouldn't be used; the Python 3 syntax will work in Python 2. Thus the following forms are deprecated: <s>
exec object in globals
exec object in globals, locals
Evaluating a string containing a Python literal with ast.literal_eval
If you have a string that contains Python literals, such as strings, floats etc, you can use
ast.literal_eval to evaluate its value instead of
eval. This has the added feature of allowing only certain syntax.
However, this is not secure for execution of code provided by untrusted user, and it is trivial to crash an interpreter with carefully crafted input
Here, the input is a string of
() repeated one million times, which causes a crash in CPython parser. CPython developers do not consider bugs in parser as security issues.
Evaluating an expression with eval
Evaluating an expression with eval using custom globals
As a plus, with this the code cannot accidentally refer to the names defined outside:
defaultdict allows for example having undefined variables set to zero:
Evaluating statements with exec
Executing code provided by untrusted user using exec, eval, or ast.literal_eval
It is not possible to use
exec to execute code from untrusted user securely. Even
ast.literal_eval is prone to crashes in the parser. It is sometimes possible to guard against malicious code execution, but it doesn't exclude the possibility of outright crashes in the parser or the tokenizer.
To evaluate code by an untrusted user you need to turn to some third-party module, or perhaps write your own parser and your own virtual machine in Python.
Precompiling an expression to evaluate it multiple times
compile built-in function can be used to precompile an expression to a code object; this code object can then be passed to eval. This will speed up the repeated executions of the evaluated code. The 3rd parameter to
compile needs to be the string