Guido van Rossum | c3d090c | 1996-10-22 01:10:56 +0000 | [diff] [blame] | 1 | \chapter{Restricted Execution} |
Fred Drake | 31ecd50 | 1998-02-18 15:40:11 +0000 | [diff] [blame] | 2 | \label{restricted} |
Guido van Rossum | c3d090c | 1996-10-22 01:10:56 +0000 | [diff] [blame] | 3 | |
Guido van Rossum | f73f79b | 1996-10-24 22:14:06 +0000 | [diff] [blame] | 4 | In general, Python programs have complete access to the underlying |
| 5 | operating system throug the various functions and classes, For |
| 6 | example, a Python program can open any file for reading and writing by |
| 7 | using the \code{open()} built-in function (provided the underlying OS |
| 8 | gives you permission!). This is exactly what you want for most |
| 9 | applications. |
Guido van Rossum | c3d090c | 1996-10-22 01:10:56 +0000 | [diff] [blame] | 10 | |
Guido van Rossum | f73f79b | 1996-10-24 22:14:06 +0000 | [diff] [blame] | 11 | There exists a class of applications for which this ``openness'' is |
| 12 | inappropriate. Take Grail: a web browser that accepts ``applets'', |
| 13 | snippets of Python code, from anywhere on the Internet for execution |
| 14 | on the local system. This can be used to improve the user interface |
| 15 | of forms, for instance. Since the originator of the code is unknown, |
| 16 | it is obvious that it cannot be trusted with the full resources of the |
| 17 | local machine. |
Guido van Rossum | c3d090c | 1996-10-22 01:10:56 +0000 | [diff] [blame] | 18 | |
Guido van Rossum | f73f79b | 1996-10-24 22:14:06 +0000 | [diff] [blame] | 19 | \emph{Restricted execution} is the basic framework in Python that allows |
Guido van Rossum | c3d090c | 1996-10-22 01:10:56 +0000 | [diff] [blame] | 20 | for the segregation of trusted and untrusted code. It is based on the |
| 21 | notion that trusted Python code (a \emph{supervisor}) can create a |
Guido van Rossum | f73f79b | 1996-10-24 22:14:06 +0000 | [diff] [blame] | 22 | ``padded cell' (or environment) with limited permissions, and run the |
Guido van Rossum | c3d090c | 1996-10-22 01:10:56 +0000 | [diff] [blame] | 23 | untrusted code within this cell. The untrusted code cannot break out |
| 24 | of its cell, and can only interact with sensitive system resources |
Guido van Rossum | f73f79b | 1996-10-24 22:14:06 +0000 | [diff] [blame] | 25 | through interfaces defined and managed by the trusted code. The term |
| 26 | ``restricted execution'' is favored over ``safe-Python'' |
Guido van Rossum | c3d090c | 1996-10-22 01:10:56 +0000 | [diff] [blame] | 27 | since true safety is hard to define, and is determined by the way the |
| 28 | restricted environment is created. Note that the restricted |
| 29 | environments can be nested, with inner cells creating subcells of |
Guido van Rossum | f73f79b | 1996-10-24 22:14:06 +0000 | [diff] [blame] | 30 | lesser, but never greater, privilege. |
Guido van Rossum | c3d090c | 1996-10-22 01:10:56 +0000 | [diff] [blame] | 31 | |
| 32 | An interesting aspect of Python's restricted execution model is that |
Guido van Rossum | f73f79b | 1996-10-24 22:14:06 +0000 | [diff] [blame] | 33 | the interfaces presented to untrusted code usually have the same names |
Guido van Rossum | c3d090c | 1996-10-22 01:10:56 +0000 | [diff] [blame] | 34 | as those presented to trusted code. Therefore no special interfaces |
| 35 | need to be learned to write code designed to run in a restricted |
| 36 | environment. And because the exact nature of the padded cell is |
| 37 | determined by the supervisor, different restrictions can be imposed, |
| 38 | depending on the application. For example, it might be deemed |
| 39 | ``safe'' for untrusted code to read any file within a specified |
| 40 | directory, but never to write a file. In this case, the supervisor |
| 41 | may redefine the built-in |
| 42 | \code{open()} function so that it raises an exception whenever the |
| 43 | \var{mode} parameter is \code{'w'}. It might also perform a |
| 44 | \code{chroot()}-like operation on the \var{filename} parameter, such |
| 45 | that root is always relative to some safe ``sandbox'' area of the |
| 46 | filesystem. In this case, the untrusted code would still see an |
Guido van Rossum | f73f79b | 1996-10-24 22:14:06 +0000 | [diff] [blame] | 47 | built-in \code{open()} function in its environment, with the same |
Guido van Rossum | c3d090c | 1996-10-22 01:10:56 +0000 | [diff] [blame] | 48 | calling interface. The semantics would be identical too, with |
| 49 | \code{IOError}s being raised when the supervisor determined that an |
| 50 | unallowable parameter is being used. |
| 51 | |
Guido van Rossum | f73f79b | 1996-10-24 22:14:06 +0000 | [diff] [blame] | 52 | The Python run-time determines whether a particular code block is |
| 53 | executing in restricted execution mode based on the identity of the |
| 54 | \code{__builtins__} object in its global variables: if this is (the |
| 55 | dictionary of) the standard \code{__builtin__} module, the code is |
| 56 | deemed to be unrestricted, else it is deemed to be restricted. |
| 57 | |
| 58 | Python code executing in restricted mode faces a number of limitations |
| 59 | that are designed to prevent it from escaping from the padded cell. |
| 60 | For instance, the function object attribute \code{func_globals} and the |
| 61 | class and instance object attribute \code{__dict__} are unavailable. |
| 62 | |
Guido van Rossum | c3d090c | 1996-10-22 01:10:56 +0000 | [diff] [blame] | 63 | Two modules provide the framework for setting up restricted execution |
| 64 | environments: |
| 65 | |
| 66 | \begin{description} |
| 67 | |
| 68 | \item[rexec] |
| 69 | --- Basic restricted execution framework. |
| 70 | |
| 71 | \item[Bastion] |
| 72 | --- Providing restricted access to objects. |
| 73 | |
| 74 | \end{description} |