[Python-Dev] Challenge: Please break this! [Now with blog post]

Guido van Rossum guido at python.org
Tue Feb 24 20:23:03 CET 2009


On Mon, Feb 23, 2009 at 11:07 PM, tav <tav at espians.com> wrote:
>  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.

In fact you don't need a metaclass at all. I think you could do
something like this in your Namespace() function:

...compute ns_items as before...
class NamespaceObject(object):
  __slots__ = ()
for name, value in ns_items:
  setattr(NamespaceObject, name, value)
return NamespaceObject()

> 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')

That is a known loophole that makes anything possible (mostly
segfaults, for sure). App Engine also stops you from doing this.

> 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``

3. Disallow creating code objects from their constructor in restricted
mode. Please add this to your "restricted" patch.

(I still think your challenge would be more realistic if you didn't
share __builtins__ but instead relied on restricted mode more.)

> 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.

You can also create code objects by unmarshalling them. This should
also be prevented in restricted mode.

> 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 =)

Restricting tb_frame is probably a good idea on its own; in 3.0 you
won't have to work so hard to get access to a traceback object, since
each exception has one. OTOH traceback.py uses some things from the
frame, but maybe we'll just have to forego that (or provide selected
R/O access to some frame attributes deemed benign).

> 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}

I don't know anything about ctypes or dictionary_of(). Maybe you need
to raise an exception first so that PyType_Ready is called? The source
is in Python/traceback.c.

> 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...

I'm guessing this refers to a pseudo-implementation of sys.exc_info()
provided by rexec.py.

> 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 | tav at espians.com | +44 (0) 7809 569 369
> http://tav.espians.com | http://twitter.com/tav | skype:tavespian
>



-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)


More information about the Python-Dev mailing list