Simple and safe evaluator
George Sakkis
george.sakkis at gmail.com
Thu Jun 12 00:16:08 EDT 2008
On Jun 11, 8:15 pm, bvdp <b... at mellowood.ca> wrote:
> Matimus wrote:
>
> > The solution I posted should work and is safe. It may not seem very
> > readable, but it is using Pythons internal parser to parse the passed
> > in string into an abstract symbol tree (rather than code). Normally
> > Python would just use the ast internally to create code. Instead I've
> > written the code to do that. By avoiding anything but simple operators
> > and literals it is guaranteed safe.
>
> Just wondering ... how safe would:
>
> eval(s, {"__builtins__":None}, {} )
>
> be? From my testing it seems that it parses out numbers properly (int
> and float) and does simple math like +, -, **, etc. It doesn't do
> functions like int(), sin(), etc ... but that is fine for my puposes.
>
> Just playing a bit, it seems to give the same results as your code using
> ast does. I may be missing something!
Probably you do; within a couple of minutes I came up with this:
>>> s = """
... (t for t in 42 .__class__.__base__.__subclasses__()
... if t.__name__ == 'file').next()('/etc/passwd')
... """
>>> eval(s, {"__builtins__":None}, {} )
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 3, in <module>
IOError: file() constructor not accessible in restricted mode
Not an exploit yet but I wouldn't be surprised if there is one. Unless
you fully trust your users, an ast-based approach is your best bet.
George
George
More information about the Python-list
mailing list