I am building a website where I have a need that user should be able to evaluate some expression based from the value in DB tables, instead of using tools like pyparsing etc, I am thinking of using python itself, and have come up with a solution which is sufficient for my purpose. I am basically using eval to evaluate the expression and passing globals dict with empty __builtins__
so that nothing can be accessed and a locals dict for values from DB, if user will need some functions I can pass those too e.g.
import datetime
def today():
return datetime.datetime.now()
expression = """ first_name.lower() == "anurag" and today().year == 2010 """
print eval(expression, {'__builtins__':{}}, {'first_name':'Anurag', 'today':today})
So my question is how safe it would be , I have three criteria
Edit: IMO this is not the duplicate of Q:661084 because where it ends this one starts, I want to know even with __builtins__
blocked, can user do bad things?
eval is evil if running on the server using input submitted by a client that was not created by the developer or that was not sanitized by the developer. eval is not evil if running on the client, even if using unsanitized input crafted by the client.
overall, "eval" security, in any language, is a big issue. SQL injection attacks are just an example of such a security hole. Perl Safe has had security bugs over the years - most recent one I remember, it was safe, except for destructors on objects returned from the safe eval.
The Eval function evaluates the string expression and returns its value. For example, Eval("1 + 1") returns 2. If you pass to the Eval function a string that contains the name of a function, the Eval function returns the return value of the function.
Eval function is mostly used in situations or applications which need to evaluate mathematical expressions. Also if the user wants to evaluate the string into code then can use eval function, because eval function evaluates the string expression and returns the integer as a result.
It's completely unsafe to use eval
, even with built-ins emptied and blocked -- the attacker can start with a literal, get its __class__
, etc, etc, up to object
, its __subclasses__
, and so forth... basically, Python introspection is just too strong to stand up to a skilled, determined attacker.
ast.literal_eval
is safe, if you can live by its limitations...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With