Showing posts with label eval. Show all posts
Showing posts with label eval. Show all posts

Saturday, May 11, 2019

eval(expr_str [, globals [, locals]] )


eval(expr_str [, globals [, locals]] )

Evaluates the Python expression contained in expr_str. Although this can be a way to write more compact code, it’s potentially dangerous if you evaluate arbitrary input strings input by the user, unless the app is for your own use only.
The following example evaluates a Python expression and returns the result.
>>> a = 100
>>> eval('3 * a +55')
355
The string must contain an expression and not a statement. Therefore, assignment statements cannot be used. However, expressions can contain function calls, and function calls, in turn, can execute statements.
One way to reduce the dangers of eval is to prevent access to symbols. The globals argument, by default, gives the setting for local symbols as well. Setting this argument to an empty dictionary prevents access to symbols. (But note that built-in functions are always accessible.)
>>> eval('3 * 10 +55', {}) # This is fine.
355
>>> eval('3 * a + 55', {}) # ERROR; 'a' no longer defined
One way to bulletproof your code is to create a dictionary containing the symbols you want to be accessible; then give that dictionary as the globals argument:
>>> from math import *
>>> a = 25
>>> dict_1 = {'tan': tan, 'radians': radians, 'a': a }
>>> eval('1000 * tan(radians(a))', dict_1)
176.326980708465
The effect is to create a dictionary that restricts the eval statement to recognize only two functions (tan and radians) and one variable (a).
The locals argument isn’t used much, but you can use it to restrict access to local symbols only. In that case, it won’t usually permit access to functions.
eval('a * a + 100', {}, locals())
Although you can use the arguments to try to make eval safer, you can never fully bulletproof this usage if your application should happen to take an arbitrary string from the user and evaluate it. There are ways hackers can take advantage of such code to bring down a system. So again, take care.



Python - eval - Untrusted code


Never exec or eval Untrusted Code

Old versions of Python tried to supply tools to ameliorate the risks of using exec and eval, under the heading of “restricted execution,” but those tools were never entirely secure against the ingenuity of able hackers, and current versions of Python have therefore dropped them. If you need to ward against such attacks, take advantage of your operating system’s protection mechanisms: run untrusted code in a separate process, with privileges as restricted as you can possibly make them (study the mechanisms that your OS supplies for the purpose, such as chroot, setuid, and jail), or run untrusted code in a separate, highly constrained virtual machine. To guard against “denial of service” attacks, have the main process monitor the separate one and terminate the latter if and when resource consumption becomes excessive. Processes are covered in “Running Other Programs”.

exec and eval are unsafe with untrusted code

The function exec_with_data is not at all safe against untrusted code: if you pass it, as the argument user_code_string, some string obtained in a way that you cannot entirely trust, there is essentially no limit to the amount of damage it might do. This is unfortunately true of just about any use of both exec and eval, except for those rare cases in which you can set very strict and checkable limits on the code to execute or evaluate, as was the case for the function safer_eval.