Bottom Page

Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
 eval() function security
#1
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.
What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Quote
#2
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.
Skaperen, metulburr, buran like this post
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures

Quote
#3
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.
ndc85430 and buran like this post
Quote
#4
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.
My code examples are always for Python >=3.6.0
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Quote
#5
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
Skaperen and metulburr like this post
Quote
#6
(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.
What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Quote
#7
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.?
Quote
#8
(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
metulburr and Skaperen like this post
Quote
#9
so, you just add functions to it as needed.
What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Quote

Top Page

Forum Jump:


Users browsing this thread: 1 Guest(s)