def parseOptions(): parser = OptionParser(usage="%prog [options] -- script.py [script options] [arg1 arg2 ...]") SandboxConfig.createOptparseOptions(parser) options, argv = parser.parse_args() if not argv: parser.print_help() exit(1) config = SandboxConfig.fromOptparseOptions(options) return config, argv
def createConfig(self): config = SandboxConfig.fromOptparseOptions(self.options) config.enable('traceback') config.enable('stdin') config.enable('stdout') config.enable('stderr') config.enable('exit') config.enable('site') config.enable('encodings') config._builtins_whitelist.add('compile') config.allowModuleSourceCode('code') config.allowModule('sys', 'api_version', 'version', 'hexversion') config.allowSafeModule('sys', 'version_info') if HAVE_PYPY: config.enable('unicodedata') config.allowModule('os', 'write', 'waitpid') config.allowSafeModule('pyrepl', 'input') config.allowModule('pyrepl.keymap', 'compile_keymap', 'parse_keys') if self.options.debug: config.allowModule('sys', '_getframe') config.allowSafeModule('_sandbox', '_test_crash') config.allowModuleSourceCode('sandbox') if not config.cpython_restricted: config.allowPath(__file__) return config
def __init__(self, name, content, type=_PYTHON): """ - name: the module name (with no extension). - content: Python or JS code - type: 'js', 'py' (XXX might be removed) """ self.libtype = type self.name = name self.content = content self.namespace = {} if type == 'js': raise NotImplementedError() config = SandboxConfig('code') for module, elements in _ALLOWED_MODULES: config.allowModule(module, *elements) self.sandbox = Sandbox(config) self._load()
def parseOptions(self): parser = OptionParser(usage="%prog [options]") SandboxConfig.createOptparseOptions(parser, default_timeout=None) parser.add_option("--debug", help="Debug mode", action="store_true", default=False) parser.add_option("--verbose", "-v", help="Verbose mode", action="store_true", default=False) parser.add_option("--quiet", "-q", help="Quiet mode", action="store_true", default=False) options, argv = parser.parse_args() if argv: parser.print_help() exit(1) if options.quiet: options.verbose = False return options
def createSandboxConfig(*features, **kw): if createSandboxConfig.debug: features += ("stdout", "stderr") if (createSandboxConfig.cpython_restricted is not None) \ and ('cpython_restricted' not in kw): kw['cpython_restricted'] = createSandboxConfig.cpython_restricted if (createSandboxConfig.use_subprocess is not None) \ and ('use_subprocess' not in kw): kw['use_subprocess'] = createSandboxConfig.use_subprocess return SandboxConfig(*features, **kw)
def parseOptions(self): parser = OptionParser(usage="%prog [options]") SandboxConfig.createOptparseOptions(parser, default_timeout=None) parser.add_option("--verbose", "-v", help="Verbose mode", action="store_true", default=False) parser.add_option("--quiet", "-q", help="Quiet mode", action="store_true", default=False) options, argv = parser.parse_args() if argv: parser.print_help() exit(1) if options.quiet: options.verbose = False config = SandboxConfig.fromOptparseOptions(options) return config, options
def test_lib2to3importer_pysandbox(self): from lib2to3import import lib2to3importer from lib2to3import import prepending fixers = [ "lib2to3.fixes.fix_exec", "lib2to3.fixes.fix_long", "lib2to3.fixes.fix_unicode", "lib2to3.fixes.fix_imports", "lib2to3.fixes.fix_dict", ] with prepending(lib2to3importer(fixers, "sandbox")): from sandbox import Sandbox from sandbox import SandboxConfig from sandbox import SandboxError box = Sandbox(SandboxConfig(use_subprocess=True)) self.assertRaises(SandboxError, box.call, print, "123")
def execute(session_id, code): global modules if code.strip() == '': return '' buff = StringIO() __stdout = sys.stdout sys.stdout = buff sandbox = Sandbox(SandboxConfig('stdout')) old_commands = get_old_commands(key=session_id) old_code = '\n'.join(old_commands) try: sandbox.execute(old_code + '\n' + code) except Exception: buff = StringIO() traceback.print_exc(file=buff) # Remove the stack trace stack = buff.getvalue().replace('"<string>"', '"<JSON-RPC>"').split('\n') return '\n'.join([stack[0]] + stack[3:]) else: full_output = buff.getvalue() output_len = get_old_output_len(key=session_id) write_code(key=session_id, code=code) expire_key(key=session_id, timeout=SESSION_TIMEOUT) if output_len: buff.seek(int(output_len)) output = buff.read() else: output = buff.getvalue() write_output_len(key=session_id, output=full_output) return output finally: sys.stdout = __stdout
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"
config = json.load(f) # configure the sandbox features = [ 'regex', 'help', 'time', 'datetime', 'itertools', 'random', 'hashlib', 'codecs', 'encodings', # 'stdout' # TODO: remove ] cfg = SandboxConfig(*features) cfg.timeout = 1 cfg.allowSafeModule('json', 'loads', 'dumps') cfg.allowSafeModule('copy', 'copy', 'deepcopy') cfg.max_memory = 100 sandbox = Sandbox(cfg) connection = pymongo.Connection("localhost", 27017) db = getattr(connection, config['db']) db.bots.ensure_index('name', unique=True) db.botdata.ensure_index('botname', unique=True) ADDR = config['socket']
import sys from sandbox import Sandbox, SandboxConfig, builtins def func(a, b): return 'hello' class Foo(object): def __init__(self, age): self.age = age sandbox = Sandbox(SandboxConfig('stdout')) f = open('exec_file_test.py').read() foo = Foo(31) cod = compile(f, 'exec_file_test.py', 'exec') exec(cod, {}, {}) # sandbox.execute(cod, locals={'foo': foo})
def __init__(self, robot_controller): super(Player, self).__init__() self.robot_controller = robot_controller config = SandboxConfig(use_subprocess=False) config.enable('traceback') config.enable('stdout') config.enable('stderr') config.enable('time') # TODO need to allow *all* imports from team package config.allowModule(robot_controller.robot.team + '.player', 'RobotPlayer') # TODO need a better method for override the sys_path config.sys_path = config.sys_path + (os.getcwd(),) # add additional builtins to the config # - increment_clock this = self def increment_clock(amt): Scheduler.instance().increment_bytecode(amt) # TODO need a better method to add builtins additions config._builtins_additions = { 'increment_clock': increment_clock, } self.sandbox = Sandbox(config) self.running = False
Examples: /eval 1+2 3 /eval zip(*[[1,2],[3,4]]) [(1,3), (2,4)]""" import re import traceback import sys #pip install pysandbox from sandbox import Sandbox, SandboxConfig from chatbot import send, p config = SandboxConfig("encodings", "math") config.timeout = 5 sandbox = Sandbox(config) def on_message(message): r = re.search(r"\/eval (.+)", message['message']) if not r: return try: ns = {'__result': None} sandbox.execute("import math; __result = " + r.group(1), locals=ns) res = unicode(ns['__result']) if len(res) > 500: res = res[:500] + " ..." send(message['topic']['id'], res) #we're running code, any error could throw an exception
def createSandboxConfig(*features, **kw): if createSandboxConfig.debug: features += ("stdout", "stderr") return SandboxConfig(*features, **kw)