The <module> Tag

A Proposed Solution to the Mashup Security Problem

Douglas Crockford
douglas@crockford.com
2006-10-30

Mashups

Mashups are an interesting new way to build applications. A mashup can combine programs and data services from multiple sources on a single page. Using JavaScript as the glue, these components and connections can be combined on a page in novel ways, inexpensively producing valuable new products. Mashups use the browser as a sort of Lego platform, allowing the snapping together of interesting new things from existing things.

Unfortunately, mashups do not work when any of the components contains information that is private or represents a connection which is private. JavaScript does provide some privacy through closure, but its reliance on a single global object for linkage does not permit cooperation under mutual suspicion. The DOM is even worse. Every node is linked directly or indirectly to every other node. It is impossible to show something to the user without also exposing it to all of the scripts that are running in the page.

The <iframe> structure confines components such that they cannot attack each other, but the Same Origin Policy isolates them so completely that they are also unable to cooperate. Mashups need to cooperate.

Rich media ads are mashups. The ad script has access to all of the information on the page, including cookies and the authenticated connection to the originating server.

The design of the current browser did not anticipate this level of integration. The current security model is intended to protect one site from another. Mashups require a finer-grained solution.

Modules

I propose a new HTML tag for partitioning a page into a collection of modules.

<module id="NAME" src="URL" style="STYLE" />

A module has three attributes. The attributes are id, which is used by scripts to gain access to the module node, src, which is the url of either a script file or an HTML file, and style, which is used to set the size and location of the module. (There may turn out to be addition attributes.)

A module has two nodes. The outer node is exposed only to the outer document. The inner node is the module's window object. Scripts on one side of the module barrier are unable to call scripts on the other side to to access or modify the other side's data structures or document structures. Communication between the outer and inner nodes is permitted only using a send/receive mechanism.

The outer node presents a send method which allows for sending a JSON string to a script of the inner node.

The outer node can accept a receive method which allows for receiving a JSON string from the module.

The inner node has a global send function which allows for sending a JSON string to the outer document's script.

The inner node can accept a receive function which allows for receiving a JSON string from the outer document's script.

If a send method is called, and a receive method has not been defined on the other side, then an exception will be thrown.

Communication is permitted only through cooperating send and receive functions. Communication is restricted only to JSON text. JSON text allows exchange of simple or complex data structures without the capability leakage that would occur with the exchange of JavaScript objects.

A module cannot be forced to give up its secrets, nor can a module force a document to give up its secrets. A module may cooperate with a page. A page may choose to facilitate communication between modules.

The module is exempt from the Same Origin Policy. The capability of a module to communicate with a page depends solely on cooperative use of send and receive functions. The origins of the module and the page are irrelevant.

The CSS display property of a module must be static. Every node in the module's parent chain must also have a CSS display property of static. A module will have a z-index space which is strictly above its parent container's space. Modules cannot have negative CSS margins. Modules cannot be clipped by the CSS clip property. These rules are to ensure that an evil container cannot place buttons or input fields on top of a module. A module should be observant of its current size.

Proposal

This proposal is offered with the intent of beginning the process of reaching a consensus on a new browser security model. Web application development has gotten significantly ahead of browser technology. The browsers need to catch up and quickly.

This proposal requires no change to JavaScript, and only a small incremental change to HTML.

It is proposed that the <module> tag (or an equivalent solution) be implemented in all makes of web browser as soon as possible.