On Sat, 11 Apr 2009 11:03:16 +0200, Joel Hedlund wrote: > Peter Otten wrote: >> But what you're planning to do seems more like >> >>>>> def is_it_safe(source): >> ... return "_" not in source >> ... >>>>> source = "getattr(42, '\\x5f\\x5fclass\\x5f\\x5f')" if >>>>> is_it_safe(source): >> ... print eval(source) >> ... >> <type 'int'> > > Bah. You are completely right of course. > > Just as a thought experiment, would this do the trick? > > def is_it_safe(source): > return "_" not in source and r'\' not in source > > I'm not asking because I'm hellbent on having eval in my app, but > because it's always useful to see what hazards you don't know about.
Can we pass your test and still write to a file? Too easy. >>> file('spam.txt', 'r') # prove that the file doesn't exist Traceback (most recent call last): File "<stdin>", line 1, in <module> IOError: [Errno 2] No such file or directory: 'spam.txt' >>> >>> source = "4+(file('spam.txt', 'w').write('spam spam spam') or 0)+5" >>> if is_it_safe(source): ... print eval(source) ... 9 >>> file('spam.txt', 'r').read() 'spam spam spam' Can we pass your test and import a module and grab its docstring? >>> source = "getattr(eval(chr(90+5)*2+'im'+'por'+'t'+chr(None or >>> 95)*2+'('+chr(39)+'os'+chr(39)+')'), chr(95)*2+'doc'+chr(99-4)*2)" >>> if is_it_safe(source): ... eval(source) ... "OS routines for Mac, NT, or Posix depending ... " Restricting Python is hard. No, not hard. It's *REALLY HARD*. Experts have tried and failed. A good example is Tav's recent attempt to secure Python code from *one* threat: writing a file on the local disk. Should be simple, right? If only. http://tav.espians.com/a-challenge-to-break-python-security.html The first exploit came an hour after Tav went public. You can read the discussion on the Python-Dev list starting here: http://mail.python.org/pipermail/python-dev/2009-February/086401.html More here: http://tav.espians.com/paving-the-way-to-securing-the-python-interpreter.html http://tav.espians.com/update-on-securing-the-python-interpreter.html My recommendation is that you do one of these: (1) Give up on making your code "safe". Recognise that the threat is relatively small, but real, and put a warning in your documentation about the risk to user's own system if they evaluate arbitrary code, and then just use eval and hope for the best. (2) Decide that you don't want your calculate to be a full-fledged programming language, and give up on making eval safe. Write your own mini-parser to do arithmetic expressions. It's really not that difficult: really easy with PyParsing, and not that hard without. -- Steven -- http://mail.python.org/mailman/listinfo/python-list