Misty Programming Language:

Security

Conventional programming languages give too much power to programs. Typically, any program is potentially capable of doing anything that the system is capable of doing. This makes sense to programmers because programmers want powerful tools. But it shouldn't make sense for anyone else because systems are unable to adequately defend themselves against malicious or imprudent programs. Attempts to add security features to existing systems have proven to be sadly (and painfully and expensively) ineffective. Archaic measures like file permissions are based on the assumption that individuals are responsible for the security properties of the programs they run. Security management software which alerts the user to potentially dangerous actions are worse than ineffective: Most people cannot possibly be expected to know how to correctly respond to those interruptions. Ineffective security measures at best allow us to blame the victim, particularly when the fault lies not with the victim but with insecure system designs.

Misty takes a different approach. Instead of attempting to add security, it makes it possible to remove sources of insecurity. It does this by giving each object in an application just the resources it needs in order to do its work and no more. The potential amount of intentional or unintentional mischief is substantially reduced. It is as if there is a firewall around every single object in the application. Misty does this while introducing no additional run-time overhead.

Misty is able to do this because it is an Object-Capability System. Secrets and powerful actions can be hidden behind objects that will properly control access. This is object-oriented security.

In an Object-Capability System, there are exactly three ways in which to obtain an object reference:

  1. By Creation. When an object is made, it may be endowed by its creator with references.
  2. By Construction. A request to construct an object will return a reference to that object.
  3. By Introduction. Invocations can carry object references. References can only be passed directly from an entity to entities of its immediate acquaintance.

No other means are possible. References cannot be obtained by simply knowing the name of something (such as 'root'), or by pointer-arithmetic, or from global variables or public class variables. With this level of object containment, if two pieces of hostile code are loaded in the same process, they will not be able to call each other or exchange object references without there first being an introduction.

With such containment, object references become tokens of authority. If a function has a reference to an object, then it has the authority to interact with that object.

In order to provide containment in a dynamic, augmentable object environment, two special operators have been provided.

object

The object operator provides indirect access to an object. The original object cannot be modified through the new object, but mutable members of the original object can be modified.

fix

The fix operator takes a reference to an object or array and returns an immutable reference to that object or array. A fixed reference prevents some actions:

Nothing can be changed. Attempting to change a property through a fixed reference will raise a 'fix' exception.

All values obtained with the reference will be fixed.

The only actions permitted with a fixed reference are read only data access and invocation of functions.

Any attempt to modify an object with an immutable reference will fail. Any references obtained from the members will also be immutable. Since immutable objects cannot be changed, they cannot be tampered with or used as rendezvous sites.

Methods of a fixed object are execute only. Attempting to get a function from a fixed object reference will produce the null value instead.

The fix operator does not modify the object itself, only to the reference. Any mutable values stored in the object or array remain mutable.

The fix operator has no effect on values that are already immutable.

A method of a fixed object is allowed to modify the immutable object. The get and put processors ignores the fixation of $ if the reference was made directly through $.

Objects

Object references should always be fixed before they are passed through a trust boundary. A fixed object allows read-only access to its data members, and invocation of its functions.

Getting a value from an object or setting a value on an object never causes a transfer of control (except in the case where an exception is raised).

Methods and functions

Functions are first class immutable values and can be stored in and retrieved from objects.

Care should be taken when assigning a method to a property of an object because that method will get a capability to the object when the method is invoked. The is method operator can be used to protect against this.

Lambda

Misty functions are lambdas. They bind context with a specific set of parameters and statements. This binding (or closure) provides mechanisms for creating private variables. Functions only have access to the values they are bound to.

Facets

A facet is an object or function that acts as an intermediary. A facet can provide a limited interface to a more powerful object or function. A facet can filter, check, and validate requests. For example, a file system facet might permit access to only certain directories, or prevent files from growing beyond a certain size. The facet object looks to the application like a file system object, but the operations it permits are limited.

Facets can also be used to provide revocability. A facet can be ordered by its issuer to become inert, which effectively prevents the application from making further use it it. A facet can also be constructed to work only once and then become inert.

Latent Properties

Objects can use other objects as property keys. Since objects are capabilities, latent properties can be accessed only when holding both the object and the key.

define latent := {}    # hold the undiscoverable key


my_object[latent]      # using the key

The for statement and the object.keys method hide object keys.

Environment

The security of the Misty language depends on the security of the run-time environment. The interfaces that are provided should practice Capability Discipline.