| \chapter{Restricted Execution \label{restricted}} |
| |
| In general, Python programs have complete access to the underlying |
| operating system throug the various functions and classes, For |
| example, a Python program can open any file for reading and writing by |
| using the \function{open()} built-in function (provided the underlying |
| operating system gives you permission!). This is exactly what you want |
| for most applications. |
| |
| There exists a class of applications for which this ``openness'' is |
| inappropriate. Take Grail: a Web browser that accepts ``applets,'' |
| snippets of Python code, from anywhere on the Internet for execution |
| on the local system. This can be used to improve the user interface |
| of forms, for instance. Since the originator of the code is unknown, |
| it is obvious that it cannot be trusted with the full resources of the |
| local machine. |
| |
| \emph{Restricted execution} is the basic framework in Python that allows |
| for the segregation of trusted and untrusted code. It is based on the |
| notion that trusted Python code (a \emph{supervisor}) can create a |
| ``padded cell' (or environment) with limited permissions, and run the |
| untrusted code within this cell. The untrusted code cannot break out |
| of its cell, and can only interact with sensitive system resources |
| through interfaces defined and managed by the trusted code. The term |
| ``restricted execution'' is favored over ``safe-Python'' |
| since true safety is hard to define, and is determined by the way the |
| restricted environment is created. Note that the restricted |
| environments can be nested, with inner cells creating subcells of |
| lesser, but never greater, privilege. |
| |
| An interesting aspect of Python's restricted execution model is that |
| the interfaces presented to untrusted code usually have the same names |
| as those presented to trusted code. Therefore no special interfaces |
| need to be learned to write code designed to run in a restricted |
| environment. And because the exact nature of the padded cell is |
| determined by the supervisor, different restrictions can be imposed, |
| depending on the application. For example, it might be deemed |
| ``safe'' for untrusted code to read any file within a specified |
| directory, but never to write a file. In this case, the supervisor |
| may redefine the built-in \function{open()} function so that it raises |
| an exception whenever the \var{mode} parameter is \code{'w'}. It |
| might also perform a \cfunction{chroot()}-like operation on the |
| \var{filename} parameter, such that root is always relative to some |
| safe ``sandbox'' area of the filesystem. In this case, the untrusted |
| code would still see an built-in \function{open()} function in its |
| environment, with the same calling interface. The semantics would be |
| identical too, with \exception{IOError}s being raised when the |
| supervisor determined that an unallowable parameter is being used. |
| |
| The Python run-time determines whether a particular code block is |
| executing in restricted execution mode based on the identity of the |
| \code{__builtins__} object in its global variables: if this is (the |
| dictionary of) the standard \refmodule[builtin]{__builtin__} module, |
| the code is deemed to be unrestricted, else it is deemed to be |
| restricted. |
| |
| Python code executing in restricted mode faces a number of limitations |
| that are designed to prevent it from escaping from the padded cell. |
| For instance, the function object attribute \member{func_globals} and |
| the class and instance object attribute \member{__dict__} are |
| unavailable. |
| |
| Two modules provide the framework for setting up restricted execution |
| environments: |
| |
| \localmoduletable |
| |
| \begin{seealso} |
| \seetitle[http://www.python.org/doc/howto/rexec/] |
| {Restricted Execution HOWTO} |
| {Andrew Kuchling's tutorial on the use of the restricted |
| execution facilities in Python.} |
| \seetitle[http://grail.sourceforge.net/]{Grail Home Page} |
| {Grail, an Internet browser written in Python, uses these |
| modules to support Python applets. More |
| information on the use of Python's restricted execution |
| mode in Grail is available on the Web site.} |
| \end{seealso} |