OpenAjax Hub 2.0 Design Comments

From MemberWiki

Jump to: navigation, search

Contents

OpenAjax Hub 2.0 Design Comments

This page contains commentary about aspects of the design of OpenAjax Hub 2.0. For example:

  • Why does the mandatory IframeContainer have a load timeout, but mandatory InlineContainers does not?
  • Why should an IframeContainer implementation hide an iframe window that has not yet connected?
  • Why should publish-subscribe be anonymous?

This page is not a normative part of the OpenAjax Hub 2.0 specification.

Unlike the 2.0 specification, these notes are a work in progress.

Hub Architecture

This section contains commentary on the basic Hub architecture.

Anonymous Publish/Subscribe

In an "anonymous" publish/subscribe hub architecture, the hub does not tag every message with the identity of the message's publisher. Publishers can optionally include identifying information in published messages, but this is an opt-in system, and it is up to recipients or the manager application to validate these claims. The OpenAjax Hub has an anonymous publish/subscribe architecture.

Not all pub/sub hub architectures are anonymous. Some such architectures are, to coin a term, attributed. Like reporters attributing comments to officials in a news story, attributed publish/subscribe hubs identify the sender of each event.

There are many different messaging systems. The architecture of each system is a product of its requirements and its environment. Some messaging systems, driven by their specific requirements, follow the "attributed" model. Others implement the anonymous model.

The OpenAjax Hub implements an anonymous publish/subscribe system. The hub does not tag every event with the identity of the event's publisher. In this section, I will explain why this architecture best suits the Hub's purpose and environment.

OpenAjax Hub Purpose and Environment

Before going on, let's review the purpose of the OpenAjax Hub and consider the environment in which it operates.

The OpenAjax Hub allows a JavaScript application within a web page to incorporate and mash up rich "widget" and data components, while isolating these components for security reasons.

This isolation involves "sandboxing" these components so that they cannot directly access either the mash-up or each other. The only way for the components to communicate is via the Hub.

Hub traffic is governed by a security manager provided by the mash-up application, which enforces security constraints data flow to and from each component.

The Hub and mash-up application play the role of middleman between publishers and subscribers. Communication between components is only as trustworthy as the middleman.

Possible Reasons for Using Attributed Pub/Sub

In this section, I first consider some possible reasons why an attributed approach might be proposed. I then explain where the attributed approach breaks down in a mash-up environment like that of the Hub, and discuss alternative approaches using an anonymous architecture.

One might consider proposing an attributed pub/sub architecture in order to address the following challenges:

1. Allow subscribers to enforce data security constraints, e.g. my component only trusts components X, Y and Z as sources of topic T and wants to enforce this constraint itself.

2. Cycle detection, e.g. a gadget receives messages, transforms them and republishes them. It does not want to get into a loop, so it needs a way to recognize its own messages, so that it can ignore them.

3. Application level functionality, e.g. a "return address" to which a gadget can send replies.

Problems with the Security Rationale

In the previous section, we said that one might propose an attributed pub/sub architecture in order to allow subscribers to enforce data security constraints. For example, component X may only trust components Y and Z as sources of events whose topic is T, and X may want to enforce this security constraint itself.

Under such an approach, the "identity" associated with a publisher would typically be the publisher's origin rather than its container ID.

Unfortunately, this proposal runs into a number of problems.

1. This architecture neglects the fact that all traffic between sandboxed components flows through a middleman: the Managed Hub (and the manager application). 2. This approach fragments security management among many different components, which makes it very difficult to manage. 3. If applications use this facility, then subscribe security uses a completely different mechanism than publish security, because this approach does nothing to prevent unauthorized subscriptions. 4. This architecture makes it difficult to use bridge components that forward messages between the Hub and a similar event system.

1. Don't Forget the Middleman!

This architecture neglects the fact that traffic does not actually flow directly from the publisher to the subscriber. All traffic between sandboxed components flows through a middleman: the Managed Hub (and the manager application). If the manager application is untrustworthy, then the manager could meddle with the Managed Hub, e.g. forging messages that seem to come from other components. A sandboxed subscriber can only trust the Managed Hub's word that an event was sent by a particular publisher.

Specifically, if there is a concern that the messenger has been compromised or that it may be a malicious forger of messages, a gadget should absolutely not accept events from the manager application unless there is no requirement that these events be real and not forged.

Conversely, a manager application should only accept subscriptions from a gadget if the manager is willing to shoulder the responsibility of making sure that it only allows events published by trustworthy publishers to reach the subscriber.

In general, each component delegates significant security responsibilities to the manager application. A component should only accept messages from a Managed Hub if the component trusts the manager application in the following ways.

  • The component must trust that the manager application is honest - that it does not deliberately carry out attacks on its own behalf (including event forgery).
  • The component must trust that the manager application is a good judge of character - that it does not accept events from publishers which, themselves, are not trustworthy, and that it does not inline components that are untrustworthy.
  • The component must trust that the manager application is secure and cannot be easily hacked.

Since every gadget is relying on the security and integrity of the manager application in any case, one should askwhy the gadget needs to appropriate to itself the task of rejecting inbound events based on their purported origins? One of the features of the purportedly trusted manager application is the ability to control which origins are allowed to send a given type of event to each subscriber. If the manager is truly trusted, why not allow it to do its job rather than performing redundant event filtering in the gadget?

Furthermore, if gadget developers become habituated to thinking of the (purported) origin of the publisher as a sufficient mark of the trustworthiness of a published event, they will tend to forget that the (purported) origin, and the message as a whole, is only as reliable as the middleman that delivered them - the manager application containing the Managed Hub.

The architecture of the OpenAjax Hub encourages developers to use the correct mental model. In contrast, an architecture in which gadgets use purported publisher origins for security purposes encourages developers to use a flawed mental model that can lead to security lapses.

2. Fragmented Security Management

If an application adopts this architecture, security management becomes fragmented among many different components that exist in different origins. It becomes very difficult for the mash-up to manage security.

The OpenAjax Hub is designed to permit the manager application (the mash-up) to control which components are allowed to publish and subscribe. Security settings can be changed entirely within the mash-up application, rather than requiring communication between the mash-up and sandboxed components or requiring seperate management interfaces for different components.

3. Controlling Subscribe vs. Publish Privileges

Suppose that an application architecture relies on gadgets to throw away events from "unreliable" publishers, and that it determines the reliability of a publisher based on its purported origin as claimed by the Managed Hub. Even if this architecture prevents a subscriber from receiving events from an untrusted publisher, it does nothing to prevent untrustworthy subscribers from receiving events that they should not be permitted to see.

Thus, an architecture that relies on purported event origins on one side must still use a different mechanism on the other.

4. Problems with Event Bridges

Bridge gadgets connect two gadget eventing systems. For example, a prototype bridge has been built between the OpenAjax Managed Hub and the OpenSocial pub/sub router. If a bridge gadget integrates the Managed Hub with a multi-origin eventing system, then all foreign events that the gadget publishes on the Managed Hub will be mislabeled with the gadget's origin, regardless of the origin of the original sender.

While under normal circumstances, such mislabeling might merely be a nuisance, the problem becomes crippling if gadgets rely on event origin labels to determine the trustworthiness of inbound events. If event origins are known to be incorrect, then a subscriber's only option is to refuse to accept any events published by the bridge.

An alternative, of course, is to allow the manager application to override the default event labeling mechanism. However, once this provision is added, equivalent behavior can be implemented under the existing anonymous Managed Hub architecture.

Problems with the Cycle-Detection Rationale

Suppose there is a component that receives messages, transforms them and republishes them. The component needs some sort of cycle detection mechanism. One approach would be for the component to be able to recognize its own messages, so that it can ignore them.

There are two major issues with this approach.

1. It only works for cycles of length 1. Even simple cycles of length 2 defeat it. 2. It requires that gadgets be labeled not with origins, but rather with component IDs.

The first point is rather obvious.

The second point is important because it indicates that the approach for cycle detection (component based publisher labeling) is incompatible with the origin- based publisher labeling approach that would be required for security management.

Note that origin-based labeling would fail because every inline Container has the same origin as the mash-up application. So origins cannot uniquely specify publishers.

Problems with the Return-Address Rationale

A publisher might provide a return address to which reply events might be sent.

Like the cycle detection mechanism, a return-address mechanism requires that events be labeled with container IDs rather than origins, indicating that this mechanism is incompatible with the origin-based publisher labeling that would be required for security management.

Problems of Attributed Pub/Sub

An attributed pub/sub has other problems.

1. In a situation where a mash-up contains components controlled by two competitors, a mash-up component from one competitor should not be able to tell that there are components from the other competitor in the mash-up, or what info is being published by the other competitor.

2. A mash-up should be able to avoid giving untrusted components information about its implementation and its other components. An attributed pub/sub system automatically shares such information.

3. In particular, exposing origin information might enable an attacker to craft postMessage based attacks.

4. Gadgets should not be forced to reveal their origins to other gadgets that might not be trustworthy.

Alternative Approach Using the OpenAjax Hub

In certain cases, certain publishers may indeed be willing to identify their origins to subscribers, and the manager application may be willing to verify these claims.

Such requirements can be easily met using the OpenAjax Managed Hub in conjunction with a simple convention, despite the fact that the Hub implements an anonymous pub/sub model. For example, publishers might include in each event a property called "publisherOrigin", which contains the origin in which the publisher claims to be running.

The manager application's onPublish function can then verify a publisher's claim using the following simple logic:

   myOnPublish = function( topic, data, pcont, scont ) {

       // ...Do other checks here...

       if( ( data["publisherOrigin"] ) &&
           ( data.publisherOrigin != pcont.getPartnerOrigin() ) ) { //LIAR!
           return true;
       return true;
   }

Because this logic is not hard-coded in the Hub, the application can override or extend this logic to support specialized requirements. For example, bridge gadgets can be supported easily because the myOnPublish logic above can be extended to allow trusted bridge gadgets to specify different origins for different senders:

   myOnPublish = function( topic, data, pcont, scont ) {

       // ...Do other checks here...

       if( ( data["publisherOrigin"] ) {
           if( data.publisherOrigin != pcont.getPartnerOrigin() ) ) {
               if( pcont.getPartnerOrigin() != aTrustedOrigin )
                   return false;
				// Otherwise the publisher is the bridge. We trust its 
				// labeling of published events, even if the origins that 
				// it specifies differ from the bridge's own origin.
           }      
       }
       return true;
   }

This logic enables the trusted bridge gadget to specify the actual origin of an event that it is forwarding, instead of the bridge's own origin.

Security Features

Frame Phishing: Load Time-Out

The anti-frame-phishing logic uses timeouts to ensure that a client that has just been loaded authenticates itself to the container in a reasonable period of time. This prevents an attacker (possibly script running in a grandparent frame) from replacing the client with a phishing document before other anti-phishing components (tunnel iframes) can be initialized.

I made the container auto-hide the iframe until the client connects (and after the client disconnects) in order to prevent a user from being tricked by such a phishing attack.

However, hiding the iframe does not prevent the phishing page from running script. If allowing the (hidden) phishing page to run script for an indefinite period of time introduces a dangerous security loophole, then the load timeout is critical because it limits the amount of time available to the script in the phishing page.

On the other hand, there are several possible mitigating factors.

1. One likely form of attack that a phishing page might mount would be an attempt to crack, by brute force, the second security token. However, this attack will be detected as a "forged message" security alert without requiring a load timeout.

2. The "phishing window" situation can't occur at all unless some malicious script in the browser has the ability to replace the container iframe's content with a phishing page (i.e., to introduce malicious script into the mash-up, one must first introduce malicious script into the mash-up). Thus, unless there are advantages to running malicious script in the container's iframe rather than an ancestor frame, one can ask why the malicious script would waste effort navigating the container iframe to a page containing some other malicious script.

Needham-Schroeder-Lowe Handshake

The NSL Handshake

When an IframeHubClient connects to an IframeContainer, the Container must ensure that the HubClient is really running in the required URL (i.e. the iframe has not been navigated to a different page) and the HubClient must ensure that the Container really has the URL that it claims to have (in case the client application is only supposed to exchange data with certain mash-up applications).

This mutual authentication relies on a handshake that is analogous to the Needham-Schroeder-Lowe protocol.[1] The reference implementation of the OpenAjax Hub implements the fixes identified in the aforementioned paper.

In the FIM case, the NSL handshake for the iframe case is roughly as follows:

1. Container → HubClient: TokenCH, TunnelURL

2. HubClient → Container: TokenCH, TokenHC, HubClient

3. Container → HubClient: TokenCH, TokenHC

...

4+. Container → HubClient: TokenCH, TokenHC, Data messages

4+. HubClient → Container: TokenCH, TokenHC, Data messages

The Container sends messages to its HubClient by setting Container iframe's src URL. This URL is is only readable by script in windows that share that URL's origin, although any origin can set this URL.

The HubClient sends messages to its Container by setting the tunnel iframe's src URL. This URL is only readable via by windows with the same origin as the tunnel URL (although any origin can set this URL). Script running in the tunnel iframe document then accesses functions within its grandparent window; this can only happen if the tunnel iframe src URL has the same origin as the manager application window.

In message #1, TunnelURL is both a return address for replies and a claim of identity. The HubClient considers the tunnel URL to represent the identity of the manager application, e.g. for getPartnerOrigin() purposes.

When a tunnel iframe receives a message via its tunnel URL, it verifies that the first of the message's two tokens is identical to TokenCH, which the Container sent to the HubClient that owns the tunnel URL. If the token is not TokenCH, then the Container raises a ForgedMessage security alert; only a HubClient instance can send messages to that HubClient's Container through HubClient's tunnel.

References

[1] Securing Frame Communication in Browsers. Adam Barth, Colin Jackson, John Mitchell. http://www.adambarth.com/papers/2008/barth-jackson-mitchell.pdf

Container Architecture

Widgets that Share an Origin

A set of widgets that trust each other completely, and which need to share information in a tightly coupled manner, must be able to share a single domain. The Managed Hub design makes it easy to accomplish this; the manager application can simply specify appropriate domains when it sets the iframe URIs for the various Containers.

Purpose of this Page

Commentary on this page serves to fill in part of the "big picture," and can be used in situations like these:

  • If an external project is considering adopting the Hub in place of its existing event system, these notes help the architects to understand the Hub architecture and to determine whether it addresses gaps in their existing system. Also, these notes may help them to feel comfortable that the Hub balances strong security with simplicity and a lightweight architecture.
  • Knowledge that is now locked up in my brain, or those of the other key developers, will inevitably be lost if it is not written down.
  • These notes may help future members to "ramp up."
  • If design changes are proposed in certain areas, these notes will help the team to determine whether newly proposed designs leave any gaps in comparison with existing approaches.
  • These notes may help us to analyze and eventually jettison features that are no longer necessary.
  • These notes may help developers of custom Containers to learn from the experience of the Hub team.
Personal tools