def test_type_bases(): from sys import version_info if version_info < (2, 6): raise SkipTest("tests disabled on Python < 2.6") code = unindent(''' def test(): class A(object): pass class B(object): pass class X(A): pass X.__bases__ = (B,) if not issubclass(X, B): raise AttributeError("__bases__ error") ''') unsafe_code = code + unindent(''' try: test() except AttributeError, err: assert str(err) == "__bases__ error" else: assert False ''') createSandbox().execute(unsafe_code) safe_code = code + unindent(''' test() ''') execute_code(safe_code)
def test_func_globals(): code = unindent(''' SECRET = 42 def get_secret_from_func_globals(): def mysum(a, b): return a+b try: func_globals = mysum.func_globals except AttributeError: # Python 2.6+ func_globals = mysum.__globals__ return func_globals['SECRET'] ''') unsafe_code = code + unindent(''' try: get_secret_from_func_globals() except AttributeError, err: assert str(err) == "'function' object has no attribute '__globals__'" else: assert False ''') createSandbox().execute(unsafe_code) safe_code = code + unindent(""" assert get_secret_from_func_globals() == 42 """) execute_code(safe_code)
def test_del_builtin(): code = unindent(''' def del_builtin_import(): import_func = __builtins__['__import__'] dict.__delitem__(__builtins__, '__import__') try: try: import sys except NameError as err: assert str(err) == "type object 'dict' has no attribute '__setitem__'" finally: __builtins__['__import__'] = import_func ''') unsafe_code = code + unindent(''' try: del_builtin_import() except AttributeError as err: assert str(err) == "type object 'dict' has no attribute '__delitem__'" except SandboxError as err: assert str(err) == "Read only object" else: assert False ''') config = createSandboxConfig() config.allowModule('sys') Sandbox(config).execute(unsafe_code)
def test_builtins_init(): import warnings code = unindent(''' def check_init(): __builtins__.__init__({}) def check_dict_init(): try: dict.__init__(__builtins__, {}) except ImportError as err: assert str(err) == 'Import "_warnings" blocked by the sandbox' except DeprecationWarning as err: assert str(err) == 'object.__init__() takes no parameters' else: assert False ''') unsafe_code = code + unindent(''' check_init() ''') try: createSandbox().execute(unsafe_code) except SandboxError as err: assert str(err) == "Read only object", str(err) else: assert False
def test_builtins_setitem(): code = unindent(''' def builtins_superglobal(): if isinstance(__builtins__, dict): __builtins__['SUPERGLOBAL'] = 42 assert SUPERGLOBAL == 42 del __builtins__['SUPERGLOBAL'] else: __builtins__.SUPERGLOBAL = 42 assert SUPERGLOBAL == 42 del __builtins__.SUPERGLOBAL ''') unsafe_code = code + unindent(''' try: builtins_superglobal() except SandboxError as err: assert str(err) == "Read only object" else: assert False ''') createSandbox().execute(unsafe_code) safe_code = code + unindent(''' builtins_superglobal() ''') execute_code(safe_code)
def test_builtins_init(): import warnings code = unindent(''' def check_init(): __builtins__.__init__({}) def check_dict_init(): try: dict.__init__(__builtins__, {}) except ImportError, err: assert str(err) == 'Import "_warnings" blocked by the sandbox' except DeprecationWarning, err: assert str(err) == 'object.__init__() takes no parameters' else: assert False ''') unsafe_code = code + unindent(''' check_init() ''') try: createSandbox().execute(unsafe_code) except SandboxError, err: assert str(err) == "Read only object", str(err)
def test_builtins_setitem(): code = unindent(''' def builtins_superglobal(): if isinstance(__builtins__, dict): __builtins__['SUPERGLOBAL'] = 42 assert SUPERGLOBAL == 42 del __builtins__['SUPERGLOBAL'] else: __builtins__.SUPERGLOBAL = 42 assert SUPERGLOBAL == 42 del __builtins__.SUPERGLOBAL ''') unsafe_code = code + unindent(''' try: builtins_superglobal() except SandboxError, err: assert str(err) == "Read only object" else: assert False ''') createSandbox().execute(unsafe_code) safe_code = code + unindent(''' builtins_superglobal() ''') execute_code(safe_code)
def test_del_builtin(): code = unindent(''' def del_builtin_import(): import_func = __builtins__['__import__'] dict.__delitem__(__builtins__, '__import__') try: try: import sys except NameError, err: assert str(err) == "type object 'dict' has no attribute '__setitem__'" finally: __builtins__['__import__'] = import_func ''') unsafe_code = code + unindent(''' try: del_builtin_import() except AttributeError, err: assert str(err) == "type object 'dict' has no attribute '__delitem__'" except SandboxError, err: assert str(err) == "Read only object" else: assert False ''') config = createSandboxConfig() config.allowModule('sys') Sandbox(config).execute(unsafe_code)
def test_modify_builtins_dict(): code = unindent(''' def builtins_dict_superglobal(): __builtins__['SUPERGLOBAL'] = 42 assert SUPERGLOBAL == 42 del __builtins__['SUPERGLOBAL'] ''') unsafe_code = code + unindent(''' try: builtins_dict_superglobal() except AttributeError as err: assert str(err) == "type object 'dict' has no attribute '__setitem__'" else: assert False ''') try: createSandbox().execute(unsafe_code) except SandboxError as err: assert str(err) == "Read only object"
def test_modify_builtins_dict(): code = unindent(''' def builtins_dict_superglobal(): __builtins__['SUPERGLOBAL'] = 42 assert SUPERGLOBAL == 42 del __builtins__['SUPERGLOBAL'] ''') unsafe_code = code + unindent(''' try: builtins_dict_superglobal() except AttributeError, err: assert str(err) == "type object 'dict' has no attribute '__setitem__'" else: assert False ''') try: createSandbox().execute(unsafe_code) except SandboxError, err: assert str(err) == "Read only object"
def test_call_exec_builtins(): code = unindent(''' result = [] exec "result.append(type(__builtins__))" in {'result': result} builtin_type = result[0] assert builtin_type != dict ''') config = createSandboxConfig() if HAVE_PYPY: # FIXME: is it really needed? config._builtins_whitelist.add('compile') Sandbox(config).execute(code)
def test_closure(): code = unindent(''' def read_closure_secret(): def createClosure(secret): def closure(): return secret return closure func = createClosure(42) try: cell = func.func_closure[0] except AttributeError: # Python 2.6+ cell = func.__closure__[0] # Does Python < 2.5 have the cell_contents attribute? See this recipe, # get_cell_value(), for version without the attribute: # http://code.activestate.com/recipes/439096/ secret = cell.cell_contents assert secret == 42 ''') # Begin by a test outside the sandbox to fill the type cache unsafe_code = code + unindent(''' try: read_closure_secret() except AttributeError, err: assert str(err) == "'function' object has no attribute '__closure__'" else: assert False, "func_closure is present" ''') createSandbox().execute(unsafe_code) # Repeat the test to ensure that the attribute cache is cleared correctly safe_code = code + unindent(''' read_closure_secret() ''') execute_code(safe_code)
def test_func_defaults(): from sys import version_info if version_info < (2, 6): raise SkipTest("tests disabled on Python < 2.6") unsafe_code = unindent(''' try: open.__defaults__ except AttributeError, err: assert str(err) in ( # open is safe_open() "'function' object has no attribute '__defaults__'", # builtin open() in restricted mode "'builtin_function_or_method' object has no attribute '__defaults__'", ) else: assert False ''') if version_info < (3, 0): unsafe_code += unindent(''' try: open.func_defaults except AttributeError, err: assert str(err) in ( # open is safe_open() "'function' object has no attribute 'func_defaults'", # builtin open() in restricted mode "'builtin_function_or_method' object has no attribute 'func_defaults'", ) else: assert False ''') sandbox = createSandbox() sandbox.execute(unsafe_code)