Python Forum
eval() function security - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: General (https://python-forum.io/forum-1.html)
+--- Forum: News and Discussions (https://python-forum.io/forum-31.html)
+--- Thread: eval() function security (/thread-21253.html)



eval() function security - Skaperen - Sep-20-2019

i want to use eval() to evaluate arithmetic expressions provided by a string. the expressions may come from an untrusted source such as a web form. is there a definite way to filter the string to keep eval() safe while still allowing most arithmetic expressions? i'm thinking to allow alphanumeric and ()+-*/ and nothing else. if some other character is there just substitute None and let the web result say the expression is invalid.


RE: eval() function security - ichabod801 - Sep-20-2019

No. You are going to have to include '.' as well for decimal numbers, right? At that point you have attribute access and function calls possible. I don't think you can allow letters and have it be safe. If you need letters, I would recommend parsing the mathematical expression yourself, and not leave it to eval.


RE: eval() function security - metulburr - Sep-21-2019

I once used eval in an IRC bot to evaluate arithmetic expressions. Luckily the person was a white hat and kindly shown me an example of exploiting eval to gain access to my desktop. Had complete control to remove files or add them to my computer. I have never used eval again in a setting where there is an untrusted string. I would rather write up my own way to evaluate arithmetic expressions from now on. It might take a little more code, but it is worth it.


RE: eval() function security - DeaD_EyE - Sep-21-2019

eval or exec from unthrusted source is always a bad idea in all languages.
Even formats like XML, YAML, JSON do allow code execution. JSON does not affect the Python world, but its a valid JavaScript Object.
XML supports loops (bad) and YAML can execute Python code or other code.


RE: eval() function security - snippsat - Sep-21-2019

Can look at project that try to make it safer,most build on top of ast module.
simpleeval | ASTEVAL.
How safe the are have not i no look into.
To to do a quick test with some something that should obviously fail.
(my_env) E:\div_code\my_env
>>> from simpleeval import simple_eval
>>>
>>> simple_eval("500 + 99")
599

# eval() will try to delete
>>> eval('__import__("os").remove("spam")')
FileNotFoundError: [WinError 2] System cannot find specified file: 'spam'

# Fail
>>> simple_eval('__import__("os").remove("spam")')
simpleeval.FunctionNotDefined: Function '__import__' not defined, for expression



RE: eval() function security - Skaperen - Sep-22-2019

(Sep-21-2019, 07:00 AM)metulburr Wrote: I once used eval in an IRC bot to evaluate arithmetic expressions. Luckily the person was a white hat and kindly shown me an example of exploiting eval to gain access to my desktop. Had complete control to remove files or add them to my computer. I have never used eval again in a setting where there is an untrusted string. I would rather write up my own way to evaluate arithmetic expressions from now on. It might take a little more code, but it is worth it.
this is exactly my concern. i used to be a gray-hat hacker long ago.

i will try out simpleval and try to break it and see how that goes.


RE: eval() function security - metulburr - Sep-22-2019

it doesnt look like you can import anything with simple_eval
Error:
simpleeval.FunctionNotDefined: Function '__import__' not defined, for expression '__import__("math").fabs(-10)'.
Would there be a way to specify the modules allowed to import, such as math or decimal, etc.?


RE: eval() function security - snippsat - Sep-22-2019

(Sep-22-2019, 04:01 PM)metulburr Wrote: Would there be a way to specify the modules allowed to import, such as math or decimal, etc.?
Should work,look like is made so can extent quite easy.
>>> from simpleeval import SimpleEval
>>> from math import sqrt
>>> 
>>> s = SimpleEval(functions={"sqrt": sqrt})
>>> s.eval('sqrt(42) * 2')
12.96148139681572
Or.
>>> import simpleeval
>>> import math
>>> 
>>> simpleeval.DEFAULT_FUNCTIONS["cos"] = math.cos
>>> simpleeval.simple_eval("cos(5) * 9")
2.552959669169036



RE: eval() function security - Skaperen - Sep-23-2019

so, you just add functions to it as needed.