limited python virtual machine

Alex Martelli aleaxit at
Sat Jan 29 09:44:27 CET 2005

Nick Coghlan <ncoghlan at> wrote:

> Alex Martelli wrote:
> > Steven Bethard <steven.bethard at> wrote:
> >    ...
> > 
> >>If I could see how to go from 'object' (or 'int', 'str', 'file', etc.)
> >>to 'eval' or '__import__', that would help out a lot...
> > 
> >>>>object.__subclasses__()
> > Traipse through these, find one class that has an unbound method, get
> > that unbound method's func_globals, bingo.
> So long as any Python modules are imported using the same restricted
> environment their func_globals won't contain eval() or __import__ either.

Sure, as long as you don't need any standard library module using eval
from Python (or can suitably restrict them or the eval they use), etc,
you can patch up this specific vulnerability.

> And C methods don't have func_globals at all.

Right, I used "unbound method" in the specific sense of "instance of
types.UnboundMethodType" (bound ones or any Python-coded function you
can get your paws on work just as well).

> However, we're talking about building a custom interpreter here, so there's no

It didn't seem to me that Steven's question was so restricted; and since
he thanked me for my answer (which of course is probably inapplicable to
some custom interpreter that's not written yet) it appears to me that my
interpretation of his question was correct, and my answer useful to him.

> reason not to simply find the dangerous functions at the C-level and replace
> their bodies with "PyErr_SetString(PyExc_Exception, "Access to this operation
> not allowed in restricted build"); return NULL;".
> Then it doesn't matter *how* you get hold of file(), it still won't work.
> (I can hear the capabilities folks screaming already. . .)

Completely removing Python-level access to anything dangerous might be a
safer approach than trying to patch one access route after another, yes.

> Combine that with a pre-populated read-only sys.modules and a restricted
> custom interpreter would be quite doable. Execute it in a separate process
> and things should be fairly solid.

If you _can_ execute (whatever) in a separate process, then an approach
based on BSD's "jail" or equivalent features of other OS's may be able
to give you all you need, without needing other restrictions to be coded
in the interpreter (or whatever else you run in that process).


More information about the Python-list mailing list