Daum-Lycos Developer Conference 2008

Security in a User Extensible System

OpenSocial is framework for building widgets. We decided to allow those widgets to be embedded in Webon webpages and also to allow uses to upload and share new widgets in the gallery for others to use. As such there were a couple challenges:

  • How do you allow the user to visual drag and drop a widget and allow it to float inside the layout?
  • Widgets can execute Javascript. How do we keep widget authors from writing malicious code and if they do how do we protect the users?

As you may know, Javascript has a huge amount of access to the execution context (the page it is running on). It even has access to cookies. So a user could in theory embed a widget on the page and that widget could steal sensitive information. My talk focussed on eliminating that risk.

The way I solved the issue was by exploiting the browsers cross same policy on script execution. The same origin policy says that frames and windows inside of your browser can talk to other frames and windows only if they are from the same domain. The rule also applies to sub domain. For example:

Illustration of same origin rule

So we would host the OpenSocial widgets from widget1234.example.com and the editor from editor.example.com then use an IFrame to embed the widget on the page. Now the widget can't steal data from the editor or the webpage the widget is embedded on.

But what about sizing of the frame? Some widgets are bigger or smaller depending on the content and that size can change at runtime (while the page is open). For things like HTML divs this is no problem. Stick more text in them and they resize. IFrames don't do that.

The trick is to communicate sizing changes to the webpage the widget is embedded on.

Note to modern web developers

Nowadays you would use window.pushMessage which is supported by all modern web browsers that matter. But pushMessage didn't exist in any major browsers at the time of this talk, nevermind have the wide support it enjoys today. So instead we got a third IFrame involved.

Here's how it worked:

[diagram of iframes]

The IFrames are able to access the parent editor through the window.parent.parent property. Whatever you do don't try to access anything in the first parent while you are there. For example, trying to read window.parent.document.body will throw en error. Just ignore it and go on through.

So that's how the innermost frame can talk to the outermost frame. But not the other way around. Also the innermost frame doesn't know anything! It is just a dumb invisible frame with no content except the script. How does it know when it's parent window (the widget) has a message for the host page?

It can do that via hashes at the end of URLs. For example, I can set the URL of a frame url from "index.html" to "index.html#size=123x456" no problem. And then the frame contents can read that URL without a refresh.

Pitfall

The browser cannot read the location of the frame and if the part of the location before the hash # isn't exactly the same it will reload the entire frame creating an unnecessary refresh and call to the server. Fortunately you can read the src attribute of the frame which will be the same as the original URL.

So now you know secure widget embedding works worked in 2008.

About the Event

The Daum-Lycos Developer Conference was an anual event that brought together Lycos and Daum developers. At the time Daum, a South Korean Internet company, owned Lycos.

I was recruited for Lycos straight out of college. I was there less then a year when the employees were given the chance to submit a talk for the conference. I was one of four American talks accepted for 2008.

My talk focused on a technology I had been developing for the web publishing platform Webon. The technology allowed OpenSocial widgets to be securely embedded into the webpage that the user was building.

Where

South Korea

When

22 Oct 2008 to 24 Oct 2008