lmfit / asteval

minimalistic evaluator of python expression using ast module
https://lmfit.github.io/asteval
MIT License
176 stars 41 forks source link

asteval segfault #100

Closed mpenning closed 2 years ago

mpenning commented 2 years ago

I found a segfault case... FYI in case it's fixable...

import asteval
ast_eval = asteval.Interpreter()

# normal usage...
ast_eval("""a=12;print('Now using asteval')""")

# segfault with asteval version 0..9.25, Debian 11, Python version 3.7.0
# Ref - https://stackoverflow.com/a/35808710/667301
ast_eval('()' * 10**6)
newville commented 2 years ago

@mpenning Thanks - that's sort of unfortunate!

I have not checked if that happens with other very very very long statements. It might be reasonable to have a strict (or a runtime option for) maximum statement length. It is hard for me to envision a statement longer than 50,000 characters as ever being something other than an obvious attempt to break the interpreter. Do you agree with that?

mpenning commented 2 years ago

I have not checked if that happens with other very very very long statements. It might be reasonable to have a strict (or a runtime option for) maximum statement length. It is hard for me to envision a statement longer than 50,000 characters as ever being something other than an obvious attempt to break the interpreter. Do you agree with that?

50k characters is a reasonable limit. I think we should have a configurable parameter for the max char length when you instantiate Interpreter(). 50k could be the default... and of course have a max char len that your team is willing to support.

This came up when people were discussing how unsafe eval() is. Given the security focus that asteval wants to have, I thought it might be useful as an alternative to eval(). However, my POC segfaulted and thus we have this github issue.

As a side note, I think it may be useful to control how many parenthesis are supported as well. I don't want to pack too much into this issue... but as a side note, I think 0.9.25 has more problems than just this segfault.

newville commented 2 years ago

@mpenning OK, I'll expect to add an "max_statement_length=50000" argument to the Interpreter and raise a ValueError if the string passed in is longer than that.

And, yes, I would not be surprised to hear of other ways to segfault Python. Basically, we can blacklist everything we know about, but we can't really guarantee that we won't miss something clever ;).

mpennington-te commented 2 years ago

@newville, as one open source developer to another, thanks much for your time and support!

newville commented 2 years ago

@mpenning I think this is now resolved. Closing.