[Python-Dev] Re: Capabilities
Zooko
zooko@zooko.com
Mon, 10 Mar 2003 15:11:04 -0500
(I, Zooko, wrote the lines prepended with "> > ".)
Jeremy Hylton <jeremy@zope.com> wrote:
>
> > 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.
With capabilities, as with any other security regime, you can execute code while
denying it access to any of the standard libraries. However if you want to
provide code access to some of the standard library's privileges without
providing access to all of them, then you in any possible security regime need
(a) some way to express which privileges it gets and which it doesn't, with
sufficiently fine granularity that you can grant the privileges you want while
excluding those you must, and (b) when actually executing the code you have to
choose which specific privileges to extend.
In a capability secure language the first step, (a) is done by the language
designer. Then the library designer provides a library of bundles of
privileges, and then (b) a programmer executes the code, passing to that code
all and only those privileges which he wants that code to have.
The library designer's job is actually pretty easy -- just: 1. try to make
privileges which are likely to be wanted separately conveniently separable and
2. try to make privileges which are likely to be wanted together conveniently
bundled.
If the library designers err on either side, the application programmer can
patch it up. For example, suppose the library designer made it so that a single
object, the "os" object, contained both the "os.system()" method and the
"os.times()" method, and the programmer wants to extend the ability to get a
timestamp without extending the ability to invoke arbitrary commands. (Note:
I'm aware that os is a module and not an object, but for now I want to think of
it as an object to be passed by reference instead of as a modules to be
"import"'ed. If we continue along the cap-Python path we'll have to come back
to this.)
So the programmer just defines a proxy:
class osproxy:
def __init__(self, os):
self.os=os
def times(self):
return self.os.times()
and gives an instance of osproxy instead of the os object itself. (In practice,
when it is only a single method, you would of course prefer to just pass the
method itself. The proxy pattern is more general.)
If the library designer has erred on the other side, making separate objects for
each of a dozen different related and innocuous functions, the programmer will
very likely define one object which contains all of those functions and pass a
reference to that object where he would have had to pass a dozen references to a
dozen functions.
I may have made too big a deal about this originally. I just spent a few
minutes browsing through modindex.html (parts of which I am already intimately
familiar with), and nothing jumped out at me as needing to be wrapped or
refactored before it could be used in a cap-Python. Perhaps the Python Standard
Library's natural modularity has already gotten us most of the way there.
> > 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.
No, "Only Connectivity Begets Connectivity" is just the "pointer-safety"
requirement -- that one can't get a reference to an object, except by either
(a) creating the object, or (b) getting the reference from some other object
which already had the reference.
Hm. Yes, that page doesn't really talk about library design. The authors of
E performed a project [1] for DARPA in which they implemented a web browser
which could host pluggable renderers, such that a malicious renderer was
constrained in the damage it could do. (I have no idea what DARPA wants with
such a thing. ;-))
The security review team at the conclusion of the project (which included great
cryptographer David Wagner) wrote [2] that E appeared to have advanced the state
of the art without breaking a sweat. The security flaws that they uncovered
were mostly due to insufficient wrapping of the Java standard libraries. For
example, the E folks had allowed an object to access a Java "File" object so
that it could access a single file, without realizing that the Java File object
has a "getParentFile()" method which returns the parent directory.
That was why I made such a big deal about the importance of a secure standard
library in my previous message. (As you know, Python's file objects don't have
a "getParentFile()" method, so we're already one step ahead of Java there...)
Regards,
Zooko
[1] http://www.combex.com/tech/darpaBrowser.html
[2] http://www.combex.com/papers/darpa-review/index.html