def test_stdout(): import sys config = createSandboxConfig(disable_debug=True) with capture_stdout() as stdout: def print_denied(): print "Hello Sandbox 1" try: Sandbox(config).call(print_denied) except SandboxError: pass else: assert False def print_allowed(): print "Hello Sandbox 2" config2 = createSandboxConfig('stdout') Sandbox(config2).call(print_allowed) print "Hello Sandbox 3" sys.stdout.flush() stdout.seek(0) output = stdout.read() assert output == "Hello Sandbox 2\nHello Sandbox 3\n"
def test_module_frame_restricted(): from sys import _getframe config = createSandboxConfig(cpython_restricted=True) def check_module_restricted(): restricted = _test_restricted(_getframe) assert restricted == True Sandbox(config).call(check_module_restricted) if HAVE_CSANDBOX: config = createSandboxConfig(cpython_restricted=False) def check_module_not_restricted(): restricted = _test_restricted(_getframe) assert restricted == False Sandbox(config).call(check_module_not_restricted)
def test(*lines, **kw): code = "; ".join(lines) config = createSandboxConfig() if HAVE_PYPY: # FIXME: is it really needed? config._builtins_whitelist.add("compile") Sandbox(config).execute(code, **kw)
def test_filetype_from_open_file(): def get_file_type_from_open_file(filename): try: with open(filename, "rb") as fp: return _get_file_type(fp) except SandboxError: pass try: with open(filename, "rb") as fp: return type(fp) except SandboxError: pass raise TestException("Unable to get file type") filename = READ_FILENAME config = createSandboxConfig() if config.cpython_restricted: # the CPython restricted mode denies to open any file raise SkipTest("require _sandbox") config.allowPath(filename) def get_file_type_object(): file_type = get_file_type_from_open_file(filename) try: read_first_line(file_type) except TypeError, err: assert str(err) in ("object.__new__() takes no parameters", "default __new__ takes no parameters") else:
def test_open_whitelist(): config = createSandboxConfig() if config.cpython_restricted: # the CPython restricted mode denies to open any file raise SkipTest("require _sandbox") config.allowPath(READ_FILENAME) Sandbox(config).call(read_first_line, open)
def test(*lines, **kw): code = "; ".join(lines) config = createSandboxConfig() if HAVE_PYPY: # FIXME: is it really needed? config._builtins_whitelist.add('compile') Sandbox(config).execute(code, **kw)
def test_filetype_from_open_file(): if not HAVE_CSANDBOX: # restricted mode deny to open any file raise SkipTest("require _sandbox") def get_file_type_from_open_file(filename): try: with open(filename, 'rb') as fp: return _get_file_type(fp) except SandboxError: pass try: with open(filename, 'rb') as fp: return type(fp) except SandboxError: pass raise TestException("Unable to get file type") filename = READ_FILENAME config = createSandboxConfig() config.allowPath(filename) def get_file_type_object(): file_type = get_file_type_from_open_file(filename) try: read_first_line(file_type) except TypeError, err: assert str(err) in ('object.__new__() takes no parameters', 'default __new__ takes no parameters') else:
def test_exit(): def exit_noarg(): try: exit() except SandboxError as err: assert str(err) == "exit() function blocked by the sandbox" else: assert False createSandbox().call(exit_noarg) config = createSandboxConfig("exit") def exit_1(): try: exit(1) except SystemExit as err: assert err.args[0] == 1 else: assert False import sys try: sys.exit("bye") except SystemExit as err: assert err.args[0] == "bye" else: assert False Sandbox(config).call(exit_1)
def test_stdout(): with capture_stdout() as stdout: config = SandboxConfig() def print_denied(): print "Hello Sandbox 1" try: Sandbox(config).call(print_denied) except SandboxError: pass else: assert False def print_allowed(): print "Hello Sandbox 2" Sandbox(createSandboxConfig("stdout")).call(print_allowed) print "Hello Sandbox 3" stdout.seek(0) output = stdout.read() assert output == "Hello Sandbox 2\nHello Sandbox 3\n"
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_sytem_exit(): def system_exit_denied(): try: raise SystemExit() except NameError as err: assert str(err) == "global name 'SystemExit' is not defined" except: assert False createSandbox().call(system_exit_denied) config = createSandboxConfig("exit") def system_exit_allowed(): try: raise SystemExit() except SystemExit: pass else: assert False Sandbox(config).call(system_exit_allowed) try: raise SystemExit() except SystemExit: pass else: assert False
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_random(): config = createSandboxConfig('random') if config.cpython_restricted: raise SkipTest("deny importing modules") check_random = 'import random; random.randint(1, 6)' Sandbox(config).execute(check_random)
def test_open_whitelist(): if not HAVE_CSANDBOX: # restricted python denies access to all files raise SkipTest("require _sandbox") config = createSandboxConfig() config.allowPath(READ_FILENAME) Sandbox(config).call(read_first_line, open)
def test_execute(): config = createSandboxConfig() if HAVE_PYPY: # FIXME: is it really needed? config._builtins_whitelist.add('compile') if config.use_subprocess: globals_builtins = set() else: globals_builtins = set(( '__builtins__',)) def test(*lines, **kw): code = "; ".join(lines) Sandbox(config).execute(code, **kw) test( "assert globals() is locals(), 'test_execute #1a'", "assert list(globals().keys()) == list(locals().keys()) == ['__builtins__'], 'test_execute #1b'", "x=42") namespace = {'a': 1} test( "assert globals() is locals(), 'test_execute #2a'", "assert list(globals().keys()) == list(locals().keys()) == ['a', '__builtins__'], 'test_execute #2b'", "a=10", "x=42", globals=namespace) assert set(namespace.keys()) == (set(('a', 'x')) | globals_builtins) assert namespace['a'] == 10 assert namespace['x'] == 42 namespace = {'b': 2} test( "assert globals() is not locals(), 'test_execute #3a'", "assert list(globals().keys()) == ['__builtins__'], 'test_execute #3b'", "assert list(locals().keys()) == ['b'], 'test_execute #3c'", "b=20", "x=42", locals=namespace) assert namespace == {'b': 20, 'x': 42} my_globals = {'a': 1} namespace = {'b': 2} test( "assert globals() is not locals(), 'test_execute #4a'", "assert list(globals().keys()) == ['a', '__builtins__'], 'test_execute #4b'", "assert list(locals().keys()) == ['b'], 'test_execute #4c'", "x=42", "a=10", "b=20", globals=my_globals, locals=namespace) assert set(my_globals.keys()) == (set(('a',)) | globals_builtins) assert my_globals['a'] == 1 assert namespace == {'a': 10, 'b': 20, 'x': 42} namespace = {} test('a=1', locals=namespace) assert namespace == {'a': 1}, namespace
def test_execute(): config = createSandboxConfig() if HAVE_PYPY: # FIXME: is it really needed? config._builtins_whitelist.add('compile') if config.use_subprocess: globals_builtins = set() else: globals_builtins = set(('__builtins__', )) def test(*lines, **kw): code = "; ".join(lines) Sandbox(config).execute(code, **kw) test( "assert globals() is locals(), 'test_execute #1a'", "assert list(globals().keys()) == list(locals().keys()) == ['__builtins__'], 'test_execute #1b'", "x=42") namespace = {'a': 1} test( "assert globals() is locals(), 'test_execute #2a'", "assert list(globals().keys()) == list(locals().keys()) == ['a', '__builtins__'], 'test_execute #2b'", "a=10", "x=42", globals=namespace) assert set(namespace.keys()) == (set(('a', 'x')) | globals_builtins) assert namespace['a'] == 10 assert namespace['x'] == 42 namespace = {'b': 2} test( "assert globals() is not locals(), 'test_execute #3a'", "assert list(globals().keys()) == ['__builtins__'], 'test_execute #3b'", "assert list(locals().keys()) == ['b'], 'test_execute #3c'", "b=20", "x=42", locals=namespace) assert namespace == {'b': 20, 'x': 42} my_globals = {'a': 1} namespace = {'b': 2} test( "assert globals() is not locals(), 'test_execute #4a'", "assert list(globals().keys()) == ['a', '__builtins__'], 'test_execute #4b'", "assert list(locals().keys()) == ['b'], 'test_execute #4c'", "x=42", "a=10", "b=20", globals=my_globals, locals=namespace) assert set(my_globals.keys()) == (set(('a', )) | globals_builtins) assert my_globals['a'] == 1 assert namespace == {'a': 10, 'b': 20, 'x': 42} namespace = {} test('a=1', locals=namespace) assert namespace == {'a': 1}, namespace
def test_timeout(): def denial_of_service(): try: while 1: pass except Timeout: pass config = createSandboxConfig() config.timeout = 0.1 Sandbox(config).call(denial_of_service)
def test_exec_builtins(): def check_builtins_type(): 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).call(check_builtins_type)
def test_readonly_import(): config = createSandboxConfig() config.allowModule('sys', 'version') def readonly_module(): import sys try: sys.version = '3000' except SandboxError, err: assert str(err) == "Read only object" else:
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_recusion(): def factorial(n): if n >= 2: return n * factorial(n - 1) else: return 1 config = createSandboxConfig() max_frames = config.recusion_limit + 1 try: Sandbox(config).call(factorial, max_frames) except RuntimeError, err: assert str(err) == 'maximum recursion depth exceeded'
def test_filetype_from_sys_stdout(): def get_file_type_from_stdout(): import sys return _get_file_type(sys.stdout) config = createSandboxConfig('stdout') def get_file_type_object(): file_type = get_file_type_from_stdout() try: read_first_line(file_type) except TypeError, err: assert str(err) in ('object.__new__() takes no parameters', 'default __new__ takes no parameters') else:
def test_import_whitelist(): # sys.version is allowed by the sandbox import sys sys_version = sys.version del sys config = createSandboxConfig() config.allowModule('sys', 'version') def import_sys(): import sys assert sys.__name__ == 'sys' assert sys.version == sys_version Sandbox(config).call(import_sys)
def test_bytecode(): if not HAVE_CSANDBOX: # restricted mode doesn't block creation of arbitrary code object raise SkipTest("require _sandbox") code_args = get_code_args() config = createSandboxConfig('code') config.allowModule('sys', '_getframe') try: Sandbox(config).call(exec_bytecode, code_args) except TestException, err: assert str(err) == "Unable to get code type"
def test_bytecode(): if not HAVE_CSANDBOX: # restricted mode doesn't block creation of arbitrary code object raise SkipTest("require _sandbox") code_args = get_code_args() config = createSandboxConfig() config.allowModule('sys', '_getframe') try: Sandbox(config).call(exec_bytecode, code_args) except TestException, err: assert str(err) == "Unable to get code type"
def test_proxy_module(): def check_proxy_module(): from sys import modules try: modules['sys'] except SandboxError as err: assert str(err) == "Unable to proxy a value of type <type 'module'>" else: assert False config = createSandboxConfig() config.allowModule('sys', 'modules') sandbox = Sandbox(config) sandbox.call(check_proxy_module)
def test_traceback(): def check_frame_filename(): import sys frame = sys._getframe(1) frame_code = frame.f_code frame_filename = frame_code.co_filename # it may ends with .py or .pyc assert __file__.startswith(frame_filename) config = createSandboxConfig('traceback') config.allowModule('sys', '_getframe') Sandbox(config).call(check_frame_filename) check_frame_filename()
def test_timeout_cpu_intensive(): if not createSandboxConfig.use_subprocess: raise SkipTest("timeout is only supported with subprocess") def denial_of_service(): sum(2**x for x in range(100000)) config = createSandboxConfig() config.timeout = 0.1 try: Sandbox(config).call(denial_of_service) except Timeout: pass else: assert False
def test_crash(): if not createSandboxConfig.use_subprocess: raise SkipTest("catching a crash is only supported with subprocess") def crash(): import _sandbox _sandbox._test_crash() config = createSandboxConfig() config.allowSafeModule("_sandbox", "_test_crash") sand = Sandbox(config) try: sand.call(crash) except SandboxError, err: assert str(err) == 'subprocess killed by signal 11', str(err)
def test_timeout_cpu_intensive(): if not createSandboxConfig.use_subprocess: raise SkipTest("timeout is only supported with subprocess") def denial_of_service(): sum(2 ** x for x in range(100000)) config = createSandboxConfig() config.timeout = 0.1 try: Sandbox(config).call(denial_of_service) except Timeout: pass else: assert False
def test_method_proxy(): def get_file_type_from_stdout_method(): import sys return _get_file_type(sys.stdout.__enter__()) config = createSandboxConfig("stdout") def get_file_type_object(): file_type = get_file_type_from_stdout_method() try: read_first_line(file_type) except TypeError, err: assert str(err) in ("object.__new__() takes no parameters", "default __new__ takes no parameters") else:
def test_timeout_while_1(): if not createSandboxConfig.use_subprocess: raise SkipTest("timeout is only supported with subprocess") def denial_of_service(): while 1: pass config = createSandboxConfig() config.timeout = 0.1 try: Sandbox(config).call(denial_of_service) except Timeout: pass else: assert False
def test_method_proxy(): def get_file_type_from_stdout_method(): import sys return _get_file_type(sys.stdout.__enter__()) config = createSandboxConfig('stdout') def get_file_type_object(): file_type = get_file_type_from_stdout_method() try: read_first_line(file_type) except TypeError as err: assert str(err) in ('object.__new__() takes no parameters', 'default __new__ takes no parameters') else: assert False Sandbox(config).call(get_file_type_object) file_type = get_file_type_from_stdout_method() read_first_line(file_type)
def test_readonly_import(): config = createSandboxConfig() config.allowModule('sys', 'version') def readonly_module(): import sys try: sys.version = '3000' except SandboxError as err: assert str(err) == "Read only object" else: assert False try: object.__setattr__(sys, 'version', '3000') except AttributeError as err: assert str(err) == "'SafeModule' object has no attribute 'version'" else: assert False Sandbox(config).call(readonly_module)
def test_compile(): import sys orig_displayhook = sys.displayhook try: results = [] def displayhook(value): results.append(value) sys.displayhook = displayhook def _test_compile(): exec compile("1+1", "<string>", "single") in {} assert results == [2] config = createSandboxConfig() Sandbox(config).call(_test_compile) del results[:] _test_compile() finally: sys.displayhook = orig_displayhook
def test_execfile(): if version_info >= (3, 0): raise SkipTest("execfile() only exists in Python 2.x") def execfile_test(filename): execfile(filename) from tempfile import NamedTemporaryFile with NamedTemporaryFile() as script: print >> script, "print('Hello World!')" script.flush() filename = script.name config = createSandboxConfig('stdout') try: Sandbox(config).call(execfile_test, filename) except NameError, err: assert str(err) == "global name 'execfile' is not defined" else:
def test_stdout(): with capture_stdout() as stdout: config = SandboxConfig() def print_denied(): print "Hello Sandbox 1" try: Sandbox(config).call(print_denied) except SandboxError: pass else: assert False def print_allowed(): print "Hello Sandbox 2" Sandbox(createSandboxConfig('stdout')).call(print_allowed) print "Hello Sandbox 3" stdout.seek(0) output = stdout.read() assert output == "Hello Sandbox 2\nHello Sandbox 3\n"
sandbox = createSandbox() try: sandbox.call(setDict, person) except SandboxError, err: assert str(err) == 'Read only object' except RuntimeError, err: assert str( err) == 'instance.__dict__ not accessible in restricted mode' else: assert False setDict(person) assert person.name == "victor" def test_proxy_module(): def check_proxy_module(): from sys import modules try: modules['sys'] except SandboxError, err: assert str( err) == "Unable to proxy a value of type <type 'module'>" else: assert False config = createSandboxConfig() config.allowModule('sys', 'modules') sandbox = Sandbox(config) sandbox.call(check_proxy_module)
def test_exec_builtins(): config = createSandboxConfig() Sandbox(config).execute(""" assert type(__builtins__) != dict """.strip())
createSandbox().call(valid_code) def test_exit(): def exit_noarg(): try: exit() except SandboxError, err: assert str(err) == "exit() function blocked by the sandbox" else: assert False createSandbox().call(exit_noarg) config = createSandboxConfig("exit") def exit_1(): try: exit(1) except SystemExit, err: assert err.args[0] == 1 else: assert False import sys try: sys.exit("bye") except SystemExit, err: assert err.args[0] == "bye" else: