On Thu, Jan 3, 2013 at 3:25 PM, Grant Edwards <invalid@invalid.invalid> wrote: > > I've written a small assembler in Python 2.[67], and it needs to > evaluate integer-valued arithmetic expressions in the context of a > symbol table that defines integer values for a set of names. The > "right" thing is probably an expression parser/evaluator using ast, > but it looked like that would take more code that the rest of the > assembler combined, and I've got other higher-priority tasks to get > back to. > > How badly am I deluding myself with the code below?
Given http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html and similar, I suspect the answer is "a fair bit". > def lessDangerousEval(expr): > global symbolTable > if 'import' in expr: > raise ParseError("operand expressions are not allowed to contain the > string 'import'") > globals = {'__builtins__': None} > locals = symbolTable > return eval(expr, globals, locals) > > I can guarantee that symbolTable is a dict that maps a set of string > symbol names to integer values. Using the aformentioned article as a basis, I was able to get this doozy working, albeit under Python 3: $ python3 Python 3.3.0 (default, Nov 4 2012, 17:47:16) [GCC 4.2.1 Compatible Apple Clang 4.0 ((tags/Apple/clang-421.0.57))] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> expr = "[klass for klass in ().__class__.__bases__[0].__subclasses__() if >>> klass.__name__ == >>> 'Codec'][0].encode.__globals__['__builtins__']['__im'+'port__']('os').remove" >>> eval(expr, {'__builtins__': None}, {}) <built-in function remove> >>> Since the original attack was itself devised against Python 2.x, it's highly likely that similar convoluted attacks against 2.x remain possible, unless perhaps you were use a modified interpreter. Cheers, Chris -- http://mail.python.org/mailman/listinfo/python-list