Re: Capabilities
To enforce capability access control, a language requires three things: 1. Pointer-safety. (There must not be a function available which performs the inverse of id().) Python has pointer-safety (unless a 3rd party native extension module has been executed). 2. Mandatory private data (accessible only by the object itself). Normal Python doesn't have mandatory private data. If I understand correctly, both rexec and proxies (attempt to) provide this. They also attempt to provide another safety feature: a wrapper around the standard library and builtins that turns off access to dangerous features according to an overridable security policy. 3. A standard library that follows the Principle of Least Privilege. That is, a library full of tools that you can extend to an object in order to empower it to do specific things (e.g. __builtin__.abs(), os.times(), ...) without thereby also empowering it to do other things (e.g. __builtin__.file(), os.system(), ...). Python doesn't have such a library. Now the Principle of Least Privilege approach to making a library safe is very different from the "sandbox" approach. The latter is to remove all "dangerous" tools from the toolbox (or in our case, to have them dynamically disabled by the "restricted" bit which is determined by an overridable policy). The former is to separate the tools so that dangerous ones don't come tied together with common ones. The security policy, then, is expressed by code that grants or withholds capabilities (== references) rather than by code that toggles the "restricted" bit. Of course, you can start by denying the entire standard library to restricted code, and then incrementally refactor the library or wrap it in Least-Privilege wrappers. Until you have a substantial Least-Privilege-respecting library you can't gain the big benefit of capabilities -- code which is capable of doing something useful without also being capable of doing harm. (You can gain the "sandbox" style of security -- code which is incapable of doing anything useful or harmful.) This requirement also means that there can be no "ambient authority" -- authority that an object receives even if its creator has given it no references. Regards, Zooko P.S. I learned this three-part paradigm from Mark Miller whose paper with Chip Morningstar and Bill Frantz articulates it in more detail: http://www.erights.org/elib/capability/ode/ode-capabilities.html#patt-coop
3. A standard library that follows the Principle of Least Privilege. That is, a library full of tools that you can extend to an object in order to empower it to do specific things (e.g. __builtin__.abs(), os.times(), ...) without thereby also empowering it to do other things (e.g. __builtin__.file(), os.system(), ...). Python doesn't have such a library.
Now the Principle of Least Privilege approach to making a library safe is very different from the "sandbox" approach. The latter is to remove all "dangerous" tools from the toolbox (or in our case, to have them dynamically disabled by the "restricted" bit which is determined by an overridable policy). The former is to separate the tools so that dangerous ones don't come tied together with common ones. The security policy, then, is expressed by code that grants or withholds capabilities (== references) rather than by code that toggles the "restricted" bit.
This sounds interesting, but I'm not sure I follow it. Can you elaborate by giving a couple of examples?
Of course, you can start by denying the entire standard library to restricted code, and then incrementally refactor the library or wrap it in Least-Privilege wrappers.
Until you have a substantial Least-Privilege-respecting library you can't gain the big benefit of capabilities -- code which is capable of doing something useful without also being capable of doing harm. (You can gain the "sandbox" style of security -- code which is incapable of doing anything useful or harmful.)
This requirement also means that there can be no "ambient authority" -- authority that an object receives even if its creator has given it no references.
Again, I would perhaps understand this if you gave a specific example. Is it like suid in Unix?
Regards,
Zooko
P.S. I learned this three-part paradigm from Mark Miller whose paper with Chip Morningstar and Bill Frantz articulates it in more detail:
http://www.erights.org/elib/capability/ode/ode-capabilities.html#patt-coop
The paper didn't seem immediately relevant, or perhaps it's too long-winded and I gave up before it touched upon the relevant stuff. :-( --Guido van Rossum (home page: http://www.python.org/~guido/)
On Sun, 2003-03-09 at 07:40, Zooko wrote:
3. A standard library that follows the Principle of Least Privilege. That is, a library full of tools that you can extend to an object in order to empower it to do specific things (e.g. __builtin__.abs(), os.times(), ...) without thereby also empowering it to do other things (e.g. __builtin__.file(), os.system(), ...). Python doesn't have such a library.
Now the Principle of Least Privilege approach to making a library safe is very different from the "sandbox" approach. The latter is to remove all "dangerous" tools from the toolbox (or in our case, to have them dynamically disabled by the "restricted" bit which is determined by an overridable policy). The former is to separate the tools so that dangerous ones don't come tied together with common ones. The security policy, then, is expressed by code that grants or withholds capabilities (== references) rather than by code that toggles the "restricted" bit.
Of course, you can start by denying the entire standard library to restricted code, and then incrementally refactor the library or wrap it in Least-Privilege wrappers.
Until you have a substantial Least-Privilege-respecting library you can't gain the big benefit of capabilities -- code which is capable of doing something useful without also being capable of doing harm. (You can gain the "sandbox" style of security -- code which is incapable of doing anything useful or harmful.)
If you need to rewrite all the libraries to be capability-aware, then you need to trust everyone who writes library code to understand capabilities and be thorough enough to get them right. I think this exacerbates the current problem of restricted execution in Python: The responsibility for making the system secure is spread through the interpreter. To do an audit to convince yourself the system is secure, you have to look at a lot of the interpreter. I don't see how it would help to add the standard library to the mix. It seems like we have a conflict between two design principles -- economy of mechanism and least privelege.
P.S. I learned this three-part paradigm from Mark Miller whose paper with Chip Morningstar and Bill Frantz articulates it in more detail:
http://www.erights.org/elib/capability/ode/ode-capabilities.html#patt-coop
I don't see the part of this paper that talks about library design :-). I assume that it's the first section "Only Connectivity Begets Connectivity." But I don't know if I understand how that applies to library design in concrete terms. Jeremy
participants (3)
-
Guido van Rossum
-
Jeremy Hylton
-
Zooko