guido> I can access the various class and metaclass objects guido> easily [snip]
It would've been possible to replace __call__ on the metaclass -- which, though not a security leak by itself, could've been abused for some fun. I've inlined the __metaclass__ to prevent fun of this kind. But the really tricky one so far is this hardcore hack that Paul Cannon emailed in: >>> from safelite import FileReader >>> __builtins__.TypeError = type(lambda: 0)(type(compile('1', 'b', 'eval'))(2, >>> 2, 4, 67, >>> 'y\x08\x00t\x00\x00\x01Wn\x09\x00\x01\x01a\x00\x00n\x01\x00X|\x01\x00|\x00\x00\x83\x01\x00S', >>> (None,), ('stuff',), ('g', 'x'), 'q', 'f', 1, ''), globals(), None, >>> (TypeError,)) >>> try: ... FileReader('foo', 2) ... except: ... pass ... >>> stuff.tb_frame.f_back.f_locals['open_file']('w00t', 'w').write('yaymore\n') He explains it in detail here: http://thepaulprog.blogspot.com/2009/02/safelite-exploit.html It's very cool! He uses the ``compile`` builtin to get hold of the CodeType and then uses that to construct a nifty function with custom bytecode. Turns out that with the bytecode one can grab traceback objects off of the stack!! And, from there, it's just a mere attribute access away to get hold of traceback.tb_frame! Paul, wisely, outlines the two possible options to remedy this: 1. Remove ``compile`` from the safe builtins 2. Take out ``tb_frame`` If compile is not present and given that func_code and gi_code are not present -- are there other ways of getting at the CodeType? If there aren't then getting rid of compile gives us an easy win. If getting rid of tb_frame is the approach -- then you were right Guido -- there are more variables which need to be restricted! But, this just makes the patch into 7 lines of code instead of 6, so I'm still happy =) The only thing I can't figure out is how to get rid of the attribute using ctypes for the safelite challenge as calling dictionary_of(TracebackType) in safelite.py presents a very minimal {'__doc__': None} Also, the comments in Lib/types.py states: # In the restricted environment, exc_info returns (None, None, # None) Then, tb.tb_frame gives an attribute error I can't seem to find the place in the Python source where exc_info() behaves differently under restricted mode... Thoughts on which of the two options is better would be very appreciated! And thanks for the ongoing hacks guys -- this is turning out great!! -- love, tav plex:espians/tav | t...@espians.com | +44 (0) 7809 569 369 http://tav.espians.com | http://twitter.com/tav | skype:tavespian _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com