Here's a first attempt at trusted python. I would be grateful if any python gurus could point out the, no doubt obvious, flaws. I've stopped fileobject working with patches to fileobject and frameobject. All child frames of the first 'trusted' frame are trusted (checked using inspect.getouterframes(inspect.currentframe()). Trusted is a one-way switch.
Is there anything I'm missing about the python frame structure? Is there any way of circumventing __getattribute__/__setattr__ ? Is there any way of getting to builtins once the imported __builtin__ methods are replaced? Regards Ronnie Mackay ------------------Use example------------------------ import trusted import inspect l_trusted=trusted.Trusted(inspect.currentframe(), ['eval','reload','compile','input','execfile'], [<list allowable modules>]) <...Attacks here...> --------------- trusted.py --------------- import __builtin__ class TrustedException(Exception): pass class TrustedImportException(Exception): pass class Trusted(object): def __init__(self, in_main_frame, in_exclude_builtins, in_modules): in_main_frame.trusted() # **NOTE C PATCH. REMOVE THIS TO RUN UNPATCHED object.__setattr__(self, '_m', in_modules) object.__setattr__(self, '_import', __builtin__.__import__) for l_builtin in in_exclude_builtins:#__main__.__builtins__.__dict__.keys(): __builtin__.__dict__[l_builtin]=object.__getattribute__(self, 'error') __builtin__.__import__=object.__getattribute__(self, 'trusted_import') def error(self, *args): raise TrustedException def trusted_import(self, in_name, in_globals=None, in_locals=None, in_as=None): l_globals=in_globals or globals() l_locals=in_locals or locals() l_as=in_as or [] if in_name in object.__getattribute__(self, '_m'): return object.__getattribute__(self, '_import')(in_name, l_globals, l_locals, l_as) else: raise TrustedImportException(in_name) def __setattr__(self, name, value): raise TrustedException def __getattribute__(self, name): if name != 'trusted_import': raise TrustedException return object.__getattribute__(self, name) ---------------- attempts to open a file ------------------- NOTE: These can't be reproduced without patching python Test :open('/dev/null') in the main module Result :file() constructor not accessible in trusted mode (exceptions.IOError) Test : within an imported module, open('/dev/null') Result :file() constructor not accessible in trusted mode (exceptions.IOError) Test :exec "open('/dev/null')" Result :file() constructor not accessible in trusted mode (exceptions.IOError) Test :get file from base types [(1).__class__.__bases__[0].__subclasses__()[-4]('/dev/null')] Result :file() constructor not accessible in trusted mode (exceptions.IOError) -- http://mail.python.org/mailman/listinfo/python-list