While snacking on some conference food and standing by my awesome poster I was presented with a question. I will go in to more details about the question in a later blog, but the result of the question was me reading up on Object Capability Model (OCM). This blog entry is to put my understanding of it in to words, to see if I got it right or not. The bulk of it came from a very nice paper written by Mark. S Miller titled “Capability Myths Demolished.”
Before we start lets define some terms so everyone is on the same page.
- Authority – An ability of the subject to access a resource.
- Resource – A thing to which an Authority provides access.
- Object/subject – In OCM it means encapsulation of state and behavior.
- Simple Security Property – This property requires that subjects have read access to resources only at or below their security level.
- *-Property - This property requires that subjects only have write access to resources at or below their security level.
These terms can be illustrated by an image (taken from “Capability Myths Demolished”):
An arrow from Alice to resource /etc/passwd indicates an authority that Alice possesses. The authority is of “type” read.
Now that the terms are defined let us get in to this. From a high level OCM is a programmatic approach to creating secure applications that rely on OOP principles for implementation. The idea is to remove ambiguity from the program as it applies to the capability of the subjects. This helps to avoid such things as “confused deputy” attack. I will describe this attack later in my post. To be considered OCM compliant an implementation needs to have seven properties. It is my hope to give better understanding of OCM as I talk about these properties.
Property A: No Designation without Authority.
To help understand this property better let us compare OCM to the Access Control List (ACL) Model. From high level it can be distinguished this way; In ACL model each resource knows what subject, or in ACL terms principal, can access it, and how. In Object capability model each subject knows what resource it can access and how. This is a very subtle distinction that can be easily overlooked. One way to visualize this is to imagine a directional "graph" with circles representing subjects on one side, and squares representing resources on the other side. The access rights are represented by an oval, with R for read, and W for write. The difference is arrows. In ACL model these ovals will be on a side of the resources, with arrows pointing from each access right to the subjects that can perform that action. With Object Capability model these ovals will be on the side of the subjects with arrows representing actions that these subjects can perform pointing to the different resources. So what is the implication of this? As with most thing the best way to illustrate it is with an example.
Let us imagine there are three subjects, and use our favorite players: Alice, Bob and Carol. There are also three resources: /etc/passwd, /u/markm/foo, and /etc/motd. We can represent this by a table.
/etc/passwd /u/markm/foo /etc/motd
Alice {read} {write} {}
Bob {read} {} {read}
Carrol {read} {write} {read}
In ACL model /etc/passwd will have an oval with {R,R,R}, from each there will be an arrow to Alice, Bob, and Carrol. The /u/markm/foo will have {W,W} with arrows pointing to Alice, and Carrol. There are only two entries, and no arrow to Bob, since he cannot perform any action/has any access to /u/markm/foo. The /etc/motd will have {R,R} with arrows pointing to Bob and Carrol. There are only two entries and no arrow to Alice since she has no access to/can perform any action on /etc/motd.
In the OCM Alice will have an oval with {R,W}. Arrow from R will point to /etc/passwd, and there will be an arrow from W to /u/markm/foo. This indicates that Alice can only perform two actions read /etc/passwd, and write /u/markm/foo. THATS IT, nothing else. Similar things are for Bob and Carol. Bob will have {R,R} with two arrows pointing to /etc/passwd and /etc/motd respectively. Carol will have {R,W,R} with arrows pointing to /etc/passwd,/u/markm/foo and /etc/motd respectively. So what is the big deal you might ask? Well as I understand it this means that in OCM each subjects capability not only represents which resource it can access, but with which authority. This is different from the ACL model in which it is not very clear with which authority access is being done.
This and Property D, described later, are used to prevent the confused deputy attack. From high level a confused deputy attack is type of exploit that tricks a subject, which has access to high level resource and low level resource, in to performing some malicious action on high level resource. An example that is usually used is a compiler that keeps track of its usage for billing purposes. On each invocation by the user it writes in to the BILLING file how long it took to perform the action. User does NOT have access to this file. Compiler also takes as an optional parameter a location of where to write out a log file. This is where the problem comes in. It is not clear with which authority it does it. Thus a user can specify location of the BILLING file as the location for the log file, tricking a compiler in to overwriting the file.
Property B: Dynamic Subject Creation
The direction of the arrows also has some interesting implications on how these policies are used. Since in ACL model each resource contains all the subjects, , which can act on it the model tends to be more static and coarse grained. Each time a subject is added and more importantly removed from the system resources need to be iterated over to add or remove that subject’s access. This also means that there needs to be some outside central authority that gives or revokes access of the subjects. One example of this is Administrator adding or removing users from the system and giving them certain permissions. With the capability model each subject knows what action it can perform and on which resource it can perform an action. This leads to an implementation that is more granular, and dynamic, with subject able to create and pass capability to other subjects. Now you might be wondering: “So smarty pants how are the capabilities revoked from the subject?” Well stay tuned.
I have alluded to it briefly in one of the above paragraphs, so here I just want to explicitly introduce this property.
Property C: Subject Aggregated Authority Management.
In other words in OCM model subjects manage their own authorities. In ACL model an outside entity, an "owner", with the power to edit the authorities in the resource list has this responsibility. This power usually extends to the entire ACL. This again leads to a coarser implementation compared to the OCM.
Thus far I have covered three of the seven properties. Now one might ask, “With these properties is it possible to revoke capabilities, and is it possible to limit or prevent capability propagation?” Fortunately the answer to both of these questions is “YES!”. If we look at the object capability system as a graph where nodes are subjects and edges are capabilities, then it is easy to see that “information” can only travel along the connected components. For example if Alice has capability to Bob she cannot pass it to Eve unless she also has a capability to Eve. In other words Alice can only grant access of Bob to Eve if she has access to both herself. This of course brings up a concern of what happens when we no longer “trust” Eve and want to revoke her access to Bob. This is also possible with a bit of extra work. Once again object oriented programming comes to the rescue, instead of passing to Eve direct access to Bob Alice can pass an “access object”. This object passes all the messages from Eve to Bob through athe “revocation object” that Alice holds. This way Eve is happy because she thinks she got a capability to Bob. Alice is happy because she can revoke Eve’s access, and anyone else access that Eve passed the “access object” to, at any time by instructing “revocation object” to stop forwarding the messages.
I should also mention that all of this relies on the system being able to differentiate between capabilities and data. An example that was used by Boerbert that “demonstrated” why capability model is broken goes something like this. Imagine a system where data flows up the security lattice, but not down. From unclassified to super duper need to pinky swear classified. In other words subjects can read from sources at or below their security level, and write to a higher security level, but not vice versa. Now let us introduce our favorite characters Alice, Bob, and Eve. Alice and Bob are at a low security level, and Eve is at a high security level. By definition of our system Alice has a capability to write to Bob, and Eve has a capability to read from Bob. So far so good, no information can flow from high security level to low. In the example this breaks when Alice transmits her write capability of Bob to Bob. At which point Even can read this capability and now it has acquired a write capability to Bob. This allows Eve to write to a lower security level, which violates our security assumptions. This is kind of bad; fortunately object capability systems distinguish between data and capabilities. So Alice only has the right to write data to Bob, and thus cannot use this channel to pass it’s capability to Eve.
Property D: No Ambient Authority
Quite simply it means authority needs to be explicit, and as specific as possible. In other words a subject shouldn't just have an access to command open to read a file. It should have access to capability that only allows the reading of the specific file, and authority with which it can read the file needs to be explicit. Going back to the compiler example the problem was that user could specify any location of where to write the log file, even if the user didn’t have authority to access those locations herself. In OCM model compiler subject will have a capability to write to the BILLING file, and a separate capability to write to a specific LOG file. So to make it more concrete during compiler initialization a file descriptor to the BILLING file can be passed in by the system. When user invokes a compiler instead of passing a string of where to write a LOG file user will need to pass a file descriptor to the log file. Thus both file descriptors are capabilities that compiler will have and it is clear with which authority they are invoked.
This covers major part of OCM, stay tuned for Part II.