BTW, it's perfectly possible to eliminate open() and file() from usability.
The only problem is it requires a separate instance of __bulitins__
(therefore probably a separate interpreter)

Try 1:

def fakeopen (filename, mode = 'r', buffering = 0):
...     raise NotImplementedError
...

__builtins__.open = fakeopen
__builtins__.file = fakeopen
open ('/dev/urandom', 'rb')
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "<stdin>", line 2, in fakeopen
NotImplementedError



Try 2 (no, you don't need another interpreter instance!)

def fakeopen (filename, mode = None, buffering = None):
...     raise NotImplementedError
...
newbuiltins = dict (vars (__builtins__))
env = {}
newbuiltins['open'] = fakeopen
newbuiltins['file'] = fakeopen
env['__builtins__'] = newbuiltins
# Try to do something VERBOTEN.
script = "f = open('/dev/random','r'); randombyte = f.read (1)"
exec script in env
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "<string>", line 1, in <module>
 File "<stdin>", line 2, in fakeopen
NotImplementedError
# now see what nested exec does..
...

script = """exec "f = open('/dev/random','r'); randombyte = f.read(1)";"""

exec script in env
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "<string>", line 1, in <module>
 File "<string>", line 1, in <module>
 File "<stdin>", line 2, in fakeopen
NotImplementedError
# still works!
...

Unless there is some way to access open() via modules' __builtins__
attribute, or functions' func_globals attribute..

And there is. But it's caught!

script = """exec "import os; f = os.__builtins__['open']('/dev/random','r');
randombyte = f.read(1);f.close()";"""
exec script in env
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "<string>", line 1, in <module>
 File "<string>", line 1, in <module>
IOError: file() constructor not accessible in restricted mode


I am running Python 2.6 here, and evidently setting __builtins__ in a
globals dictionary activates restricted mode for anything running in it.

Testing nestedness
# now for extreme convolution
...
script = """exec "f = open('/dev/random','r'); randombyte =
f.read(1);f.close()"
in os.__builtins__"""
exec script in env
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "<string>", line 1, in <module>
 File "<string>", line 1, in <module>
IOError: file() constructor not accessible in restricted mode

:D

Testing silly degree of nestedness:
#and ultimate convolution
...
script = """exec "exec \\\"f = open('/dev/random','r'); randombyte =
f.read(1);f.close()\\\"" in os.__builtins__"""
exec script in env
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "<string>", line 1, in <module>
 File "<string>", line 1, in <module>
 File "<string>", line 1, in <module>
IOError: file() constructor not accessible in restricted mode

So that's pretty locked-down (I haven't tested the os module -- get a
checkout of SVN python if you want to do that.)


Greg, in Python 2.6:

Python 2.6a0 (trunk:52884, Dec  1 2006, 14:21:57)
[GCC 4.0.3 (Ubuntu 4.0.3-1ubuntu5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(3).__class__.__bases__[0].__subclasses__()[-3]
<type 'deque_reverse_iterator'>

(3).__class__.__bases__[0].__subclasses__()[-29]
<type 'file'>

# It's a nice hack, but it doesn't help you evade restrictions:
exec "(3).__class__.__bases__[0].__subclasses__()[-29]('/dev/urandom')"
in env
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "<string>", line 1, in <module>
IOError: file() constructor not accessible in restricted mode


The two other major issues are looping-forever (which can't be fixed really,
except by restricting execution time) and memory usage (I accidentally
created a infinite loop today that expanded Python's memory usage to 500mb).
Greg's idea of running as a seperate process is good for addressing those.

Re: imports -- probably the only fully safe way is to prohibit them
completely, and pre-import chosen safe modules for your scripts' use.

Reply via email to