Monday, August 26, 2013

Conclusion

Identity-based access controls, and related schemes, are too coarse-grained for
the requirements of modern collaborative systems. Capabilities offer the hope
of fixing what otherwise appears to be a hopeless problem.
Furthermore, capabilities make some security options quite simple that would
otherwise be hopelessly unwieldy.
For those interested in further exploration and experimentation, I would skip
the operating system approach.
The language-based approach offers three viable alternatives, Caja, which
should be in wide use by the time this paper is published, E, which is mature
and functional, but not very much used, and Joe-E. Caja and Joe-E share
the advantage that they are based on existing languages (Javascript and Java
respectively) and so do not present a steep learning curve. E, on the other
hand, has a number of interesting features, such as built-in support for writing
distributed systems and an interesting and useful distributed message ordering
paradigm.
For distributed systems, Waterken implements a web-based approach, and,
as mentioned above, E has support at the language level.
In all cases, it makes sense to exploit the natural link between capabilities
and objects by using a language designed to handle capabilities inherently, thu

Limited Spend

Suppose I have a capability allowing unfettered access to my bank account. I
could hand a capability to Alice, who I partially trust, that could be used to
spend up to some limit directly from my bank account. Alice could then go
and buy something on my behalf using that capability ... or steal the money
from me. But Alice could not steal or spend any more than the limit I had set.
Furthermore, until Alice does actually spend the money, it remains available to
me in my bank account, so this is not the same as actually giving the money to
her.
Also, if I thought I might change my mind later, I could first wrap the bank
account capability in a revocable capability, and then wrap the revocable capability
in the limited-spend capability. Note that the limited-spend capability
would not need to know whether the account-access capability was revocable or
not.

Proving User Choice

If we don’t even trust Carol to correctly report the user’s choices in the example
above, we could elaborate this further by having the trusted renderer hand Carol
a capability which proves that the user did indeed click on the capability she is
now handing to Bob, and Bob could decline to act unless he sees that capability.

Oblivious Transport

Suppose Alice wants to tell Bob a secret, but has to do so via an intermediary,
Carol. Alice can hand Carol a capability containing the secret, which has a
method allowing access to the secret, but only if that method is also handed
a second capability. Only Bob and Alice have this second capability. Alternatively,
the second capability can have a method which can unseal the first
one.
Carol can then hand that capability on to Bob, who can then combine it
with the “unsealing” capability to access the data inside.
This may seem like an artificial construction, but consider the case where
Alice and Bob are components of a trusted system, and Carol is untrusted
code running in that system. Combining this idea with the example above, the
capability handed to Carol could also contain data which, when handed to the
trusted HTML renderer, would be made visible to the user, but which Carol
could not herself see. Carol may determine from user actions that this capability
should be used to perform some action on behalf of the user and hand it on to
Bob to do so.

Allowing Access to Dangerous Operations

Again, thinking about the browser case; in order to render untrusted code safe
it must have its output restricted so that it cannot place “dangerous” HTML
on the web page (for example, <script> tags with arbitrary Javascript). But
it may be that the container wants to allow it to use such HTML that has been
“blessed” by the container.
In this case, a capability can be used to wrap the blessed HTML. The capability
prevents the untrusted code from modifying its contents (by not providing
a method to do so), but when handed to the safe-HTML-writing capability it
bypasses the HTML safety checks and allows the blessed HTML to be written.

Advanced Uses

It has long been held that anything capabilities can do ACLs can also do. This
is not the case, and the most obvious counter example is this: if Alice wants
to give Bob access to some file, say, then in an ACL system all Alice needs to
do is add Bob to the ACL for that file. ACLs cannot prevent Alice from giving
access to Bob.
In a capability system, Alice also needs a capability giving access to Bob
in order to pass him the capability to the file[12]. Furthermore, it must be a
capability whose API allows the passing of other capabilities.
The ramifications of this difference could form the subject matter of a whole
book, but I give some examples here.

Capabilities and the Browser

The browser is an environment that is hard to imagine how to control with
ACLs, but capabilities seem to fit right in. Let’s consider a gadget, for example.
A gadget is, when you get down to it, a piece of javascript supplied by one
site running in a page supplied by another. From a security point of view this
presents an interesting dilemma: it is very likely that the user has different
levels of trust for the two pieces of code (say, for example, that the enclosing
page is Google Mail and the gadget is provided by god-knows-who) – but from
a traditional security point of view they are indistinguishable – they both run
as the same user and they are both effectively on the same page. Furthermore
the objects that one might want to protect (contact lists, contents of emails
and so forth) are effectively invisible to the operating system’s access control
mechanisms, and to the browser’s (if only it had any).
The view in a capability world could not be more different. In this case
the gadget is entirely at the mercy of the enclosing page, which can decide in
infinite detail what the gadget has access to and how. What’s more, providing
these detailed capabilities to the gadget is as easy and natural as providing
Javascript objects to it. Indeed, in the case of Caja, at least, that is precisely
how capabilities are implemented: as Javascript objects.