Title: del __builtins__ breaks out of rexec
Type: Stage:
Components: Interpreter Core Versions: Python 2.2
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: gvanrossum Nosy List: ejums, gvanrossum, nnorwitz, pedronis
Priority: low Keywords:

Created on 2002-07-04 19:01 by ejums, last changed 2002-09-15 06:03 by gvanrossum. This issue is now closed.

File name Uploaded Description Edit ejums, 2002-07-04 19:01 "del __builtins__" rexec bug unit test
Messages (5)
msg11482 - (view) Author: Eric Jacobs (ejums) Date: 2002-07-04 19:01
Executing the statement "del __builtins__" in a
restricted execution environment (say, the test shell
in causes all restrictions to be bypassed.

This is caused by the fact that restriction policies
are implemented by having the "__builtins__" key in the
globals dictionary. It is a design error to implement
restriction policies with an object that can be
modified by the restricted code!

A temporary workaround would involve a modification to

***	Sat Jun 22 22:57:46 2002
--- /home/eric/	Tue Jul  2 16:08:03 2002
*** 241,249 ****
      # Add a module -- return an existing module or
create one
      def add_module(self, mname):
!         if self.modules.has_key(mname):
!             return self.modules[mname]
!         self.modules[mname] = m =
          m.__builtins__ = self.modules['__builtin__']
          return m
--- 241,249 ----
      # Add a module -- return an existing module or
create one
      def add_module(self, mname):
!         if not self.modules.has_key(mname):
!             self.modules[mname] =
!         m = self.modules[mname]
          m.__builtins__ = self.modules['__builtin__']
          return m

However, the restriction execution feature is prone to
this sort of programming error by design, and it should
probably be fixed by having the builtins module be
specified explicitly when executing restricted code, so
that it doesn't accidentally fall back to the
unrestricted builtins inherited from the parent frame.
msg11483 - (view) Author: Neal Norwitz (nnorwitz) * (Python committer) Date: 2002-08-17 16:14
Logged In: YES 

I have tested the patch attached and it seems to work.  I
don't know if the approach is a good solution.  Guido, if
you think this is acceptable, assign to me and I'll fix it.
 Since this is a security problem should it be backported to
msg11484 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2002-08-17 20:01
Logged In: YES 

I find it hard to believe that putting __builtins__ back
once per r_exec() call would be sufficient.

What if someone wrote "del __builtins__; import socket" ?

Backporting to 2.1 sounds like giving people a false sense
of security. If there's a message to be gotten out, it is
"don't trust rexec". This fix doesn't make me more confident
but less (even if applied).
msg11485 - (view) Author: Samuele Pedroni (pedronis) * (Python committer) Date: 2002-08-25 00:28
Logged In: YES 

In jython we don't even try to support rexec.

I have checked with 1.5.2 and the problem was already 
there, which probably means rexec is understressed and 

my two cts

OTOH "don't trust rexec" is not stated in the 
documentation, and if it is really that the message that 
should go out, then maybe it is better to just deprecate 

msg11486 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2002-09-15 06:03
Logged In: YES 

I've thought about this some more, and come to the
conclusion that, while rexec should not be considered safe,
the add_module() patch is the right thing. So I've added
this to current CVS. It should be backported to 2.2 and 2.1.

My use of the interactive console had to be fixed separately
(but this is only in the CVS head so doesn't have to be
Date User Action Args
2002-07-04 19:01:15ejumscreate