[cap-talk] The Taming of the JavaScript

Kris Kowal kris.kowal at cixar.com
Fri Jun 5 17:54:04 EDT 2009


This is a call for assistance from object capability experts for an
emerging server-side JavaScript platform.  Narwhal [0] is a
standard-library for JavaScript targeting the specifications being
drawn by the ServerJS group [1].  This includes a "securable" module
loader specification that draws a narrow contract between module
providers and module consumers [2].  The present effort is to create a
file system API [3].  My motivation in involvement in this project is
to produce an ecosystem for JavaScript modules that can be used both
client and server side, in secured and permissive boxes, with a clear
migration path that permits coexistence of present-style and
future-style modules at various stages.  The narrowest track is
supporting modules in a secure box.

Narwhal is designed to support multiple JavaScript engines.
Presently, the prototype for Rhino is farthest along and works both
standalone, in servelets, and particularly on Google's AppEngine.
There are several people working on support for Mozilla's XPCOM for
both extensions and XULRunner applications, as well as V8, with the
intent of adding JavaScriptCore.  We have an alternate module loader
that works for web pages.

As much code as possible is in JavaScript that is reused across all of
the "platforms", including the initial module loader and package
loader.  Getting to this point involves a bin/narwhal shell script
that discovers its own location and the location of the platform
specific platforms/{name}/bin/platform-{name} script.  That script
launches the JavaScript engine with a platforms/{name}/bootstrap.js
script which in turn loads the common narwhal.js with an initial
"system" object.

narwhal.js loads the initial "sandbox" module manually.  The "sandbox"
module provides a full-fledged module loader with a module search path
that looks for modules first in the platform/lib/ and then the shared
lib/.  From there, it forces the loading of the platform specific
primordial patches ("global") and the platform specific "system"
module.

All modules have their own closure and receive "require", "exports",
"module", "system" and "print" as the only free variables.  "require"
grabs singleton modules and has a very narrow specified name-space
supporting both top-level and relative module paths based on the
current module's id.  Module's host their API on the "exports" object.
 The "module" object provides the information attributes "id" (for the
module's own ID), and other optional attributes depending on the
platform and sandbox, like "path" if the module is from the file
system and not in a sandbox.  The "system" object carries capabilities
into the sandbox, like "stdin", "stdout", "stderr", and "fs", all of
which are optional and discoverable with the usual "feature-testing"
we're familiar with in browsers.  The "print" function is just a
shortcut for "system.print".  "require" and "exports" are the only
names required by the specification, but "module" is on track to be
added.

The "sandbox" module can be used to cheaply create new, attenuated
systems of modules.  With platform-specific extensions a sandbox can
potentially be made "secure" by creating module factory functions in a
context with deeply frozen globals (a "hermetic evaluator").  The
module loader can be attenuated to validate module identifiers and
restrict the module search path.  The system object could be created
and frozen with attenuated capabilities.  The loader itself could be
passed safely to the sandbox so that it can create subordinate
sandboxes with even less authority.

The notion is that, bootstrapping Narwhal, you would construct a
permissive platform.  In that permissive context, you would create a
set of attenuated capability objects, then create a new sandbox.  The
sandbox would operate in the "secure" platform instead of the native
platform.  In the same way that the Rhino/Java platform gets its
authority to interact with the file system from the ambient Packages
object, the secure platform would get all of its authority from the
"system" object.  Within this system, all modules within a sandbox are
vulnerable to each other, to their loader, and to their "system", but
are only vulnerable to subordinate sandboxes through the "system" they
provide to the sandbox.

Presently Rhino does not support "hermetic eval", since the Java
"Packages" namespace refuses to be culled.  I continue searching for
ways to do this.  But, there are several efforts that would benefit
from a complete sandboxing strategy, particularly for Firefox
extensions on the xpcom platform, where it would be ideal to
instantiate a secured module system for each page, or a sandbox for
each discrete component of a page.  This could be a basis for
exploring standard modules for future ECMAScript.  Since modules would
have to be entered explicitly, we have an opportunity to make them
strict and lexically scoped by default, among other things.

We would need to set up "hermetic eval", and bring each supportable
platform up to ES5 compliance, and several other holes, but in the
interim, we would like to start this show with object capability
programming in mind.  This involves creating cross-platform modules
that attenuate their own features, like require("file").chown(path)
which would return a new "file" capability object, safe for passing to
a sandbox.  Any and all expert help, review, and teaching would be
appreciated.

Kris Kowal

[0] Narwhal http://github.com/tlrobinson/narwhal/
[1] ServerJS https://wiki.mozilla.org/ServerJS
[2] Securable Modules https://wiki.mozilla.org/ServerJS/Modules/SecurableModules


More information about the cap-talk mailing list