长风秋雁
eval是邪恶的eval("__import__('os').remove('important file')") # arbitrary commandseval("9**9**9**9**9**9**9**9", {'__builtins__': None}) # CPU, memory注意:即使您使用SET__builtins__到None仍然有可能通过内省来爆发:eval('(1).__class__.__bases__[0].__subclasses__()', {'__builtins__': None})使用astimport astimport operator as op# supported operatorsoperators = {ast.Add: op.add, ast.Sub: op.sub, ast.Mult: op.mul, ast.Div: op.truediv, ast.Pow: op.pow, ast.BitXor: op.xor, ast.USub: op.neg}def eval_expr(expr): """ >>> eval_expr('2^6') 4 >>> eval_expr('2**6') 64 >>> eval_expr('1 + 2*3**(4^5) / (6 + -7)') -5.0 """ return eval_(ast.parse(expr, mode='eval').body)def eval_(node): if isinstance(node, ast.Num): # <number> return node.n elif isinstance(node, ast.BinOp): # <left> <operator> <right> return operators[type(node.op)](eval_(node.left), eval_(node.right)) elif isinstance(node, ast.UnaryOp): # <operator> <operand> e.g., -1 return operators[type(node.op)](eval_(node.operand)) else: raise TypeError(node)您可以很容易地限制每个操作或任何中间结果的允许范围,例如限制输入参数a**b:def power(a, b): if any(abs(n) > 100 for n in [a, b]): raise ValueError((a,b)) return op.pow(a, b)operators[ast.Pow] = power或者限制中间结果的大小:import functoolsdef limit(max_=None): """Return decorator that limits allowed returned values.""" def decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): ret = func(*args, **kwargs) try: mag = abs(ret) except TypeError: pass # not applicable else: if mag > max_: raise ValueError(ret) return ret return wrapper return decoratoreval_ = limit(max_=10**100)(eval_)例>>> evil = "__import__('os').remove('important file')">>> eval_expr(evil) #doctest:+IGNORE_EXCEPTION_DETAILTraceback (most recent call last):...TypeError:>>> eval_expr("9**9")387420489>>> eval_expr("9**9**9**9**9**9**9**9") #doctest:+IGNORE_EXCEPTION_DETAILTraceback (most recent call last):...ValueError: