0.1.2 • Published 10 years ago

trezor v0.1.2

Weekly downloads
6
License
AGPL-3.0
Repository
github
Last release
10 years ago

trezor

JavaScript library to associate private data with objects via a public interface.

Usage

var trezor = require('trezor');

Create an access function by calling trezor and providing a property name used to define access methods on objects. Also provide a function which is called once for each new object passed to the resulting access function. The result may be a function called every time when the private data of an object is accessed, but it may also be a non-function value in which case this value will serve as private data. Options may be provided as third parameter in form of an object.

var access = trezor('foo', function () {
  return {};
});

// or

var access = trezor('foo', function () {
  return function () {
    return {};
  };
});

The resulting function access should only be accessible to code which is allowed to read the private data. Pass any non-null object or function to this function to retrieve the private data. For this to work, objects need to be extensible (cf. Object.isExtensible) or sealed (cf. Object.isSealed). The latter requirement is only neccessary when an access method will override an existing property of the same name.

var obj1 = {};
access(obj1).mySecret = 'XXX';

var obj2 = {};
access(obj2).mySecret = 'YYY';

After this, obj1 and obj2 will have private data with property mySecret set to 'XXX' or 'YYY' respectively. This private data is associated directly with each object by using an access method under property foo (provided to trezor).

Now the tricky part is to prevent uncontrolled access to this private data. One could simply call obj1.foo().mySecret to gain access to some object's secret. Even if the method name is not known a priori it would still be possible to determine it.

var obj = {};
access(obj);
// Get the property name just defined by call to `access`.
var name = Object.getOwnPropertyNames(obj)[0];
obj[name]();

In order to prevent this, the method defined on each object takes a private token only known to this very method. When this token is provided the method returns the private data. One could still access the private data when knowing this private token.

var SECRET_TOKEN;
var obj = {
  // Define a method of the same name to snoop the private token.
  foo: function (token) {
    // Now we would have access to the secret token.
    SECRET_TOKEN = token;
  }
}
access(obj);
obj.foo(SECRET_TOKEN).mySecret = 'Booyah!';

To avoid giving away this token to untrusted code a function must be authenticated to be a genuine access method, i.e. the access method defined by this library on any object. This is realized by a first call to the alleged access method before making a second call with the private token. The first call provides an authentication token upon which an authentic access method will return a nonce (a one-time secret) accessible only to access methods defined by this library to prove itself genuine. The second call is only made when the access method is proven to be authentic.

Options

sticky

Once can transfer an object's access method to another object by simply assignin the access method to another object using the same property name. To prevent this option sticky=true (default false) can be provided which will cause an additional check verifying that an access method's this is the same object for which the access method was once defined.

delegate

In order to still have access to an overridden method (non-function properties are lost as they are replaced by a function thus changing semantics) one can provide option delegate=true (default false). This causes any non-access calls (calls without a known token) to the access method to be delegated either to:

  • the replaced method (when a method was defined on the object itself) or
  • the method of the same name accessible on the prototype chain.

License

Licensed under the AGPL-3.0.

0.1.2

10 years ago

0.1.1

10 years ago

0.1.0

10 years ago