Skip to content
Deian Stefan edited this page Jan 23, 2012 · 3 revisions

DBCollection labels and policies

DB label

The DB label is used for access control. Specifically it is used to enforce who can read/write from/to the database. For instance, the label L_DB = <True, Alice / Bob> imposes the following restrictions:

  • anybody can read from the DB.
  • only Alice or Bob can write to the DB

Collection label

The collection label is similar to DB label, but restricts the principals that can access a collection within a DB. For instance, the label L_Coll = <Alice, Alice> imposes the restrictions:

  • only Alice can read from the DB
  • only Alice can write to the DB

In other words, the collection label can be used to impose restrictions in addition to the DB label.

Collection clearance

The collection clearance is used to impose a restriction on the data within the collection. Specifically, the sensitivity of any data in the collection is limited by the collection clearance. For instance, the clearance C_Coll = <Secret, Alice> imposes the restrictions:

  • no data may be more secret than Secret; in other words TopSecret data may exist in the collection
  • no data may be less trustworthy than Alice. In other words data created by Alice or Bob may not exist in the collection (Alice / Bob), but data endorsed by both Alice and Bob may (Alice /\ Bob).

Collection policies

Each DB+collection has two forms of policies:

  • A document policy, which specifies how a document that is to be inserted into the collection or is retrieved from the collection is to be labeled.
  • A field policy, which specifies how a document field value is to be labeled.

Each policy is a function from a document to a label. In other words, data from the document (e.g., user-name) can be used to label documents/fields.

Document

A document is a set of fields, each field being a key-value pair. A value is a LabeledBSON, meaning that it can be any of the following:

  • unlabeled BSON value
  • labeled BSON value
  • policy-labeled BSON value

The labeled BSON value is serialized as a BSON document whose key has a prefix that is internal to HAILS (__hails_internal) that no code may use when creating a document. Similarly, a policy-labeled BSON value is serialized as a BSON document with a key whose prefix is __hails_internal. We serialized labeled and policy-labeled values in this manner as to provide some guaranteed in the case of model-changes. Specifically, if version 0 of an application has the password field as a labeled string, and a later version removes (either by accident or malice) the label restriction -- it should not be the case that existing passwords be simply read as unlabeled strings.

A document policy must specify how the document should be labeled. This label protects all the values in the document. In the case of labeled or policy-labeled fields, the document label protects the label of the values.

DB Interface

MongoDB supports standard operations on collections.

Insert

Inserting a unlabeled document into a collection requires several steps:

  • Check that thread can write to DB (current label can flow to label of DB). Because an insert might fail, the current label should be raised to the join of itself and the DB label.
  • Check that thread can write to the collection. (Same as above.)
  • For each policy-labeled field in the document, apply the corresponding field policy.
  • Apply the document policy to the document.
  • Check that the label of all labeled and policy-labeled fields is below the collection clearance.
  • Check that the document label is below the collection clearance.
  • Perform actual insert.

Note that when applying the policies (i.e., performing a label operation) it is required that the label of fields/document be below the current clearance.

Inserting already-labeled documents (with labels possibly above the current clearance) is done as follows:

  • Check that thread can write to DB (as above).
  • Check that thread can write to the collection. (As above.)
  • For each policy-labeled field in the document, check that the already-labeled field has a label equal to that of the policy-generated label.
  • Check that the label of all labeled and policy-labeled fields is below the collection clearance.
  • Check that the document label matches the document-policy generated label.
  • Check that the document label is below the collection clearance.
  • Perform actual insert.

Note that if any checks in step 3-4 fail, an exception with the document label is thrown (which may be above the current clearance and thus cannot be handled).

Query

Simple Find

Fetching all documents within a collection (i.e., no predicate/WHERE clause) is done as follows:

  • Check that thread can read from DB. The current label is raised to the join of itself and the DB label.
  • Check that thread can read from collection. (Same as above.)
  • Do actual fetch, returning a cursor whose label is the join of the DB and collection label.

Simple Next

Getting the next document of a query (find) result for a no-predicate query is done as follows:

  • Check that thread can read from cursor. Raise current label to join of itself and cursor label.
  • Retrieve the actual document.
  • Apply policies to document, and return labeled document.

Find

Fetching documents within a collection given a non-vacuous predicate on unlabeled fields:

  • Check that thread can read from DB. The current label is raised to the join of itself and the DB label.
  • Check that thread can read from collection. (Same as above.)
  • Do actual fetch, returning a cursor whose label is the join of the DB and collection label.

Next

Getting the next document of a complex query (find) result is done as follows:

  • Check that thread can read from cursor. Raise current label to join of itself and cursor label.
  • Retrieve the actual document.
  • Apply policies to document.
  • Raise the current label to the join of itself and document label and return (i.e., perform an unlabel) the unlabeled document.

Note that if in the last step the document label is above the current clearance, the thread will not be able to catch the thrown exception. Note that this leaks a bit of information through termination: there exists a document that matches the given predicate.

An alternative approach can do:

  • If the document label is below the current clearance, raise the current label to the join of itself and document label and return (i.e., perform an unlabel) the unlabeled document.
  • Otherwise perform another next.

This approach, though more permissive, can be used to leak information though timing. The simple find/next can be used to retrieve all labeled documents, while the complex find/next can be used to perform a query on sensitive data. The duration of the latter query can be used to infer whether there was a match (usually longer, since a next will be performed until we can read something) and the former can be used to infer which document might have matched (the label of the document will likely have some useful information e.g. username).