Wow, how did this topic end up crossing over to this list while i wasn't looking? :0
Ben Laurie wrote:
I'll admit to being that person. A capability is, in essence, an opaque bound method. Of course, for them to be much use, you want the system to provide some other stuff, like not being able to recreate capabilities (i.e. you get hold of them from on high, and that's the _only_ way to get them).
Jeremy Hylton wrote:
That seems like a funny defintion of a capability.
A better definition of "capabilitiy" is "object reference".
"Bound method" isn't enough, because a capability should be able to have state, and your system should have the flexibility to represent capabilities that share state with other capabilities, or ones that don't. The simple, straightforward way to model this is to just equate the word "capability" with "object reference".
A capability system must have some rules for creating and copying capabilities, but there is more than one way to realize those rules in a programming language.
I suppose there could be, but there is really only one obvious way: creating a capability is equivalent to creating an object -- which you can only do if you hold the constructor. A capability is copied into another object (for the security folks, "object" == "protection domain") when it is transmitted as an argument to a method call.
To build a capability system, all you need to do is to constrain the transfer of object references such that they can only be transmitted along other object references. That's all.
The problem for Python, as Jeremy explained, is that there are so many other ways of crawling into objects and pulling out bits of their internals.
Off the top of my head, i only see two things that would have to be fixed to turn Python into a capability-secure system:
1. Access to each object is limited to its declared exposed interface; no introspection allowed.
2. No global namespace of modules (sys.modules etc.).
If there is willingness to consider a "secure mode" for Python in which these two things are enforced, i would be interested in making it happen.
The problem, which rexec solves after a fashion, is to prevent unauthorized copying of the capabilities, or more specifically of the access rights contained in the capability.
No, this isn't necessary. There's no point in restricting copying. The real problem is the unlimited introspective access ("there is no private").
In Python, there is no private.
Side note (probably irrelevant): in some sense there is, but nobody uses it. Scopes are private. If you were to implement classes and objects using lambdas with message dispatch (i.e. the Scheme way, instead of having a separate "class" keyword), then the scoping would take care of all the private-ness for you.
The Zope proxy approach seems a little more promising, because it centralizes all the security machinery in one object, a security proxy. A proxy for an object can appear virtually indistinguishable for the object itself, except that type(proxy) != type(object_being_proxied). The proxy guarantees that any object returned through the proxy is wrapped in its own proxy, except for simple immutable objects like ints or strings.
The proxy mechanism is interesting, but not for this purpose. A proxy is how you implement revocation of capabilities: if you insert a proxy in front of an object and grant access to that proxy, then you can revoke the access just by telling the proxy to stop responding.
The mechanism by which the proxy also proxies objects passing through is what we capability-nerds call a "membrane", and it's a way of doing more powerful revocation.