Georg Brandl | 8ec7f65 | 2007-08-15 14:28:01 +0000 | [diff] [blame] | 1 | |
| 2 | .. _restricted: |
| 3 | |
| 4 | ******************** |
| 5 | Restricted Execution |
| 6 | ******************** |
| 7 | |
| 8 | .. warning:: |
| 9 | |
| 10 | In Python 2.3 these modules have been disabled due to various known and not |
| 11 | readily fixable security holes. The modules are still documented here to help |
| 12 | in reading old code that uses the :mod:`rexec` and :mod:`Bastion` modules. |
| 13 | |
| 14 | *Restricted execution* is the basic framework in Python that allows for the |
| 15 | segregation of trusted and untrusted code. The framework is based on the notion |
| 16 | that trusted Python code (a *supervisor*) can create a "padded cell' (or |
| 17 | environment) with limited permissions, and run the untrusted code within this |
| 18 | cell. The untrusted code cannot break out of its cell, and can only interact |
| 19 | with sensitive system resources through interfaces defined and managed by the |
| 20 | trusted code. The term "restricted execution" is favored over "safe-Python" |
| 21 | since true safety is hard to define, and is determined by the way the restricted |
| 22 | environment is created. Note that the restricted environments can be nested, |
| 23 | with inner cells creating subcells of lesser, but never greater, privilege. |
| 24 | |
| 25 | An interesting aspect of Python's restricted execution model is that the |
| 26 | interfaces presented to untrusted code usually have the same names as those |
| 27 | presented to trusted code. Therefore no special interfaces need to be learned |
| 28 | to write code designed to run in a restricted environment. And because the |
| 29 | exact nature of the padded cell is determined by the supervisor, different |
| 30 | restrictions can be imposed, depending on the application. For example, it |
| 31 | might be deemed "safe" for untrusted code to read any file within a specified |
| 32 | directory, but never to write a file. In this case, the supervisor may redefine |
| 33 | the built-in :func:`open` function so that it raises an exception whenever the |
Sandro Tosi | 98ed08f | 2012-01-14 16:42:02 +0100 | [diff] [blame] | 34 | *mode* parameter is ``'w'``. It might also perform a :c:func:`chroot`\ -like |
Georg Brandl | 8ec7f65 | 2007-08-15 14:28:01 +0000 | [diff] [blame] | 35 | operation on the *filename* parameter, such that root is always relative to some |
| 36 | safe "sandbox" area of the filesystem. In this case, the untrusted code would |
| 37 | still see an built-in :func:`open` function in its environment, with the same |
| 38 | calling interface. The semantics would be identical too, with :exc:`IOError`\ s |
| 39 | being raised when the supervisor determined that an unallowable parameter is |
| 40 | being used. |
| 41 | |
| 42 | The Python run-time determines whether a particular code block is executing in |
| 43 | restricted execution mode based on the identity of the ``__builtins__`` object |
| 44 | in its global variables: if this is (the dictionary of) the standard |
| 45 | :mod:`__builtin__` module, the code is deemed to be unrestricted, else it is |
| 46 | deemed to be restricted. |
| 47 | |
| 48 | Python code executing in restricted mode faces a number of limitations that are |
| 49 | designed to prevent it from escaping from the padded cell. For instance, the |
| 50 | function object attribute :attr:`func_globals` and the class and instance object |
| 51 | attribute :attr:`__dict__` are unavailable. |
| 52 | |
| 53 | Two modules provide the framework for setting up restricted execution |
| 54 | environments: |
| 55 | |
| 56 | |
| 57 | .. toctree:: |
| 58 | |
| 59 | rexec.rst |
| 60 | bastion.rst |
| 61 | |
| 62 | .. seealso:: |
| 63 | |
| 64 | `Grail Home Page <http://grail.sourceforge.net/>`_ |
| 65 | Grail, an Internet browser written in Python, uses these modules to support |
| 66 | Python applets. More information on the use of Python's restricted execution |
| 67 | mode in Grail is available on the Web site. |
| 68 | |