[Python-Dev] Capabilities (we already got one) (original) (raw)

Phillip J. Eby pje@telecommunity.com
Tue, 01 Apr 2003 13:01:54 -0500


However, you don't use the same technique to control access to Python modules such as the zipfile module, because the "import zipfile" statement will give the current scope access to the zipfile module even if nobody has granted such access to the current scope. ... So your solution to this, to prevent code from grabbing privileges willy nilly via "import" and builtins, is rexec, which creates a scope in which code executes (now called a "workspace"), and allows you to control which builtins and modules are available for code executing in that "workspace".

Almost. I think you may be confusing module code and module objects. Guido pointed this out earlier.

A Python module object is populated by executing a body of code against the module object dictionary. The module object dictionary contains a 'builtins' entry that gives it its "base" capabilities.

Module objects possess capabilities, which are in their dictionary or reachable from it. Code doesn't possess capabilities except to constants used in the code. So access to code only grants you capabilities to the code and its constants.

So, in order to provide a capability-safe environment, you need only provide a custom import which uses a different 'sys.modules' that is specific to that environment. At that point, a "workspace" consists of an object graph rooted in the supplied 'builtins', locals(), globals(), and initially executing code.

We can then see that the standard Python environment is in fact a capability system, wherein everything is reachable from everything else.

The "holes" in this capability system, then, are:

  1. introspective abilities that allow "breaking out" of the workspace (such as the ability to 'sys._getframe()' or examine tracebacks to "reach up" to higher-level stack frames)

  2. the structuring of the library in ways that equate creating an instance of a class with an "unsafe" capability. (E.g., creating instances of 'file()') coupled with instance->class introspection

  3. Lack of true "privacy" for objects. (Proxies are a useful way to address this issue, because they allow more than one "capability" to exist for the same object.)