limited python virtual machine (WAS: Another scripting language implementedinto Python itself?)

A

Alex Martelli

Stephen Thorne said:
One thing my company has done is written a ``safe_eval()`` that uses
a regex to disable double-underscore access.

Alex> will the regex catch getattr(object,
Alex> 'subclasses'.join(['_'*2]*2)...?-)

Now he has two problems. ;-)

I nearly asked that question, then I realised that 'getattr' is quite
easy to remove from the global namespace for the code in question, and
assumed that they had already thought of that.

OK then -- vars(type(object)) is a dict which has [[the unbound-method
equivalent of]] object.__subclasses__ at its entry for key
'__subclasses__'. Scratch 'vars' in addition to 'getattr'. And 'eval'
of course, or else building up the string 'object.__subclasses__' (in a
way the regex won't catch) then eval'ing it is easy. I dunno, maybe I'm
just being pessimistic, I guess...


Alex
 
A

Aahz

Aahz said:
Alex Martelli deleted his own attribution:

One thing my company has done is written a ``safe_eval()`` that uses a
regex to disable double-underscore access.

will the regex catch getattr(object, 'subclasses'.join(['_'*2]*2)...?-)

Heheh. No. Then again, security is only as strong as its weakest link,
and that quick hack makes this part of our application as secure as the
rest.
 
B

Bernhard Herzog

OK then -- vars(type(object)) is a dict which has [[the unbound-method
equivalent of]] object.__subclasses__ at its entry for key
'__subclasses__'. Scratch 'vars' in addition to 'getattr'. And 'eval'
of course, or else building up the string 'object.__subclasses__' (in a
way the regex won't catch) then eval'ing it is easy. I dunno, maybe I'm
just being pessimistic, I guess...

You can defeat the regexp without any builtin besides object:
"+AG8AYgBqAGUAYwB0AC4AXwBfAHMAdQBiAGMAbABhAHMAcwBlAHMAXwBf-")

Bernhard
 
S

Skip Montanaro

Alex> I dunno, maybe I'm just being pessimistic, I guess...

No, I think you are being realistic. I thought one of the basic tenets of
computer security was "that which is not expressly allowed is forbidden".
Any attempt at security that attempts to find and plug the security holes
while leaving the basic insecure system intact is almost certainly going to
miss something.

Skip
 
A

Alex Martelli

Skip Montanaro said:
Alex> I dunno, maybe I'm just being pessimistic, I guess...

No, I think you are being realistic. I thought one of the basic tenets of
computer security was "that which is not expressly allowed is forbidden".
Any attempt at security that attempts to find and plug the security holes
while leaving the basic insecure system intact is almost certainly going to
miss something.

I guess security is drastically different from all other programming
spheres because you DO have an adversary, who you should presume to be
at least as clever as you are. In most tasks, good enough is good
enough and paranoia doesn't pay; when an adversary IS there, only the
paranoid survive...;-)


Alex
 
C

Christophe Cavalaria

Steven said:
Fuzzyman said:
Cameron Laird wrote:
[snip..]
This is a serious issue.

It's also one that brings Tcl, mentioned several
times in this thread, back into focus. Tcl presents
the notion of "safe interpreter", that is, a sub-
ordinate virtual machine which can interpret only
specific commands. It's a thrillingly powerful and
correct solution to the main problem Jeff and others
have described.

A better (and of course *vastly* more powerful but unfortunately only
a dream ;-) is a similarly limited python virutal machine.....

Yeah, I think there are a lot of people out there who would like
something like this, but it's not quite clear how to go about it. If
you search Google Groups, there are a lot of examples of how you can use
Python's object introspection to retrieve "unsafe" functions.

I wish there was a way to, say, exec something with no builtins and with
import disabled, so you would have to specify all the available
bindings, e.g.:

exec user_code in dict(ClassA=ClassA, ClassB=ClassB)

but I suspect that even this wouldn't really solve the problem, because
you can do things like:

py> class ClassA(object):
... pass
...
py> object, = ClassA.__bases__
py> object
<type 'object'>
py> int = object.__subclasses__()[2]
py> int
<type 'int'>

so you can retrieve a lot of the builtins. I don't know how to retrieve
__import__ this way, but as soon as you figure that out, you can then
do pretty much anything you want to.

Steve

Wouldn't it be better to attach to all code objets some kind of access right
marker and to create an opcode that calls a function while reducing the
access rights ? After all, security would be easier to achieve if you
prevented the execution of all the dangerous code rather than trying to
hide all the entry points to it.
 
N

Nick Coghlan

Alex said:
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.

Yes, I'd stopped following the thread for a bit, and the discussion had moved
further afield than I realised :)
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).

I think that's where these discussion have historically ended. . . making a
Python-specific sandbox gets complicated enough that it ends up making more
sense to just use an OS-based sandbox that lets you execute arbitrary binaries
relatively safely.

The last suggestion I recall along these lines was chroot() plus a monitoring
daemon that killed the relevant subprocess if it started consuming too much
memory or looked like it had got stuck in an infinite loop.

Cheers,
Nick.
 
A

Alex Martelli

Nick Coghlan said:
I think that's where these discussion have historically ended. . . making a
Python-specific sandbox gets complicated enough that it ends up making more
sense to just use an OS-based sandbox that lets you execute arbitrary binaries
relatively safely.

The last suggestion I recall along these lines was chroot() plus a monitoring
daemon that killed the relevant subprocess if it started consuming too much
memory or looked like it had got stuck in an infinite loop.

"Yes, but" -- that ``if'' at the start of this quote paragraph of mine
is, I believe, a meaningful qualification. It is not obvious to me that
all applications and platforms can usefully execute untrusted Python
code in a separate jail'd process; so, I think there would still be use
cases for an in-process sandbox, although it's surely true that making
one would not be trivial.


Alex
 
J

Jack Diederich

Yes, I'd stopped following the thread for a bit, and the discussion had
moved further afield than I realised :)


I think that's where these discussion have historically ended. . . making a
Python-specific sandbox gets complicated enough that it ends up making more
sense to just use an OS-based sandbox that lets you execute arbitrary
binaries relatively safely.

The last suggestion I recall along these lines was chroot() plus a
monitoring daemon that killed the relevant subprocess if it started
consuming too much memory or looked like it had got stuck in an infinite
loop.

The Xen virtual server[1] was recently metnioned on slashdot[2].
It is more lightweight and faster than full scale machine emulators because
it uses a modified system kernel (so it only works on *nixes it has been
ported to). You can set the virtual memory of each instance to keep
programs from eating the world. I don't know about CPU, you might still
have to monitor & kill instances that peg the CPU.

If anyone does this, a HOWTO would be appreciated!

-Jack
 
N

Nick Craig-Wood

Jack Diederich said:
The Xen virtual server[1] was recently metnioned on slashdot[2].
It is more lightweight and faster than full scale machine emulators because
it uses a modified system kernel (so it only works on *nixes it has been
ported to).

....it also uses python for its control programs.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top