Using python's eval() vs. ast.literal_eval()?

前端 未结 6 1238
情深已故
情深已故 2020-11-21 06:39

I have a situation with some code where eval() came up as a possible solution. Now I have never had to use eval() before but, I have come across p

6条回答
  •  礼貌的吻别
    2020-11-21 07:13

    eval: This is very powerful, but is also very dangerous if you accept strings to evaluate from untrusted input. Suppose the string being evaluated is "os.system('rm -rf /')" ? It will really start deleting all the files on your computer.

    ast.literal_eval: Safely evaluate an expression node or a string containing a Python literal or container display. The string or node provided may only consist of the following Python literal structures: strings, bytes, numbers, tuples, lists, dicts, sets, booleans, None, bytes and sets.

    Syntax:

    eval(expression, globals=None, locals=None)
    import ast
    ast.literal_eval(node_or_string)
    

    Example:

    # python 2.x - doesn't accept operators in string format
    import ast
    ast.literal_eval('[1, 2, 3]')  # output: [1, 2, 3]
    ast.literal_eval('1+1') # output: ValueError: malformed string
    
    
    # python 3.0 -3.6
    import ast
    ast.literal_eval("1+1") # output : 2
    ast.literal_eval("{'a': 2, 'b': 3, 3:'xyz'}") # output : {'a': 2, 'b': 3, 3:'xyz'}
    # type dictionary
    ast.literal_eval("",{}) # output : Syntax Error required only one parameter
    ast.literal_eval("__import__('os').system('rm -rf /')") # output : error
    
    eval("__import__('os').system('rm -rf /')") 
    # output : start deleting all the files on your computer.
    # restricting using global and local variables
    eval("__import__('os').system('rm -rf /')",{'__builtins__':{}},{})
    # output : Error due to blocked imports by passing  '__builtins__':{} in global
    
    # But still eval is not safe. we can access and break the code as given below
    s = """
    (lambda fc=(
    lambda n: [
        c for c in 
            ().__class__.__bases__[0].__subclasses__() 
            if c.__name__ == n
        ][0]
    ):
    fc("function")(
        fc("code")(
            0,0,0,0,"KABOOM",(),(),(),"","",0,""
        ),{}
    )()
    )()
    """
    eval(s, {'__builtins__':{}})
    

    In the above code ().__class__.__bases__[0] nothing but object itself. Now we instantiated all the subclasses, here our main enter code hereobjective is to find one class named n from it.

    We need to code object and function object from instantiated subclasses. This is an alternative way from CPython to access subclasses of object and attach the system.

    From python 3.7 ast.literal_eval() is now stricter. Addition and subtraction of arbitrary numbers are no longer allowed. link

提交回复
热议问题