Restricted Execution of untrusted code

Aaron Brady castironpi at gmail.com
Thu Oct 30 23:11:44 EDT 2008


On Oct 30, 3:50 pm, Aaron Brady <castiro... at gmail.com> wrote:
> On Oct 30, 6:35 am, "Emanuele D'Arrigo" <man... at gmail.com> wrote:
>
>
>
> > I noticed that this issue has been discussed in this newsgroup
> > periodically over the years and I seem to understand that -
> > comprehensive- safe/restricted execution of untrusted code in python
> > is currently quite hard to achieve.
>
> > What if the safety requirements are a little relaxed though? All I'd
> > want to prevent is for the code opening/damaging files, formatting
> > drives or similarly catastrophic exploits. I'm not particularly
> > concerned if the application freeze or crashes. Nor if the
> > application's objects are inspected and exploited. All I want is to
> > make sure that if somebody uses my application plus a third party
> > plugin for it, the worst that can happen is that they can't use my
> > application with that plugin.
>
> > Is that feasible?
>
> > Thanks for your help!
>
> > Manu
>
> Hi.  One opinion is that you could do it with a custom Python
> installation, removing or restricting the import statement, removing
> or restricting the os module, the file type, etc.  Here is some
> problematic code:
>
> >>> cust= (1).__class__.__bases__[0].__subclasses__()
> >>> [ x for x in cust if x.__name__== 'file' ]
>
> [<type 'file'>]
>
> The foreign code can get to the 'file' type.  If you don't have it,
> that's not a problem.
>
> Otherwise, you might be able to remove access to it by modifying
> however it is the 'cust' list is obtained.  Perhaps you can use the
> technique that's used to change the value of integers.  Keep us
> posted.  Does this give you any ideas?

The hackery I was referring to makes a cut into this particular
vulnerability.  It empties the 'tp_subclasses' field of 'object', but
who knows how else one could get to it?

from _ctypes import _cast_addr
_data_cast= c.PYFUNCTYPE(c.py_object, c.py_object, c.py_object,
c.py_object)(_cast_addr)
x= _data_cast( object, None, c.c_void_p )
y= _typeobject.from_address( x.value )
y.tp_subclasses= 0  #<--- dirty work done here (embarassed)
assert (1).__class__.__bases__[0].__subclasses__()== [] #<--- (!!!)

Though, oddly enough,

_data_cast( object, None, _typeobject )

doesn't work.



More information about the Python-list mailing list