#!/usr/bin/env python #socat tcp-listen:2060,fork exec:./sandbox.py,pty,stderr import re num_pattern = re.compile(r'^[\d]{0,4}$') operator_pattern = re.compile(r'^[\W]+$') del re if __name__ == '__main__': class Detangle: str = str repr = repr dir = dir eval = eval filter = filter log = True exclude = { '__builtins__': ('print',), } forbidden = ('__builtins__.open', '__builtins__.file') def __init__(self): self.intercept('__builtins__') def intercept(self, module_str, module = None): self.log = False module = module if module else self.eval(module_str) for f in self.filter(lambda f: not f in self.exclude[module_str], module.__dict__): func = self.eval('module.' + f, {'module': module}) module.__dict__[f] = self.Interceptor(func, module_str + '.' + f, self) self.log = True class Interceptor: def __init__(self, orig, func, detangle): self.orig = orig self.func = func self.d = detangle self.to_str = self.d.str(orig) self.to_repr = self.d.repr(orig) def __call__(self, *args, **kwargs): if self.func in self.d.forbidden: raise SystemExit('That is forbidden'); result = self.orig(*args, **kwargs) if self.d.log: if self.func == '__builtins__.__import__': if args[0] not in self.d.exclude: raise SystemExit('Sandbox breaking detected.') self.d.intercept(args[0], result) args = ', '.join([self.d.repr(p) for p in args]) kwargs = ', '.join(['{0} = {1}'.format(k, v) for k, v in kwargs.items()]) param = args + ', ' + kwargs if kwargs else args print('Debug: {0}({1}) # {2}'.format(self.func, param, self.d.repr(result))) return result def __str__(self): return self.to_str def __repr__(self): return self.to_repr Detangle = Detangle() del Detangle ## sandboxed code num1 = raw_input('Number 1: ') num2 = raw_input('Number 2: ') operator = raw_input('Operator: ') if not num_pattern.match(num1) or not num_pattern.match(num2): raise SystemExit('Number rejected') if not operator_pattern.match(operator) or len(operator) > 1900: raise SystemExit('Operator rejected') del num_pattern del operator_pattern operator = eval(operator) if "'" in operator else operator print(eval(num1 + operator + num2))