Archive for the ‘oframebust’ Category

Pick your busts with oFrameBust

Sunday, April 12th, 2009

Update 04-13-09: In focusing on cross-domain communication, I completely overlooked the obvious solution: document.referrer. Assuming document.referer works reliably for iframes cross browser, tather than using oframebust, sites should just do:

(function(){
   var whitelist = ['digg.com', 'facebook.com', 'www.facebook.com'];
   if (window.top.location != window.location) {
      var match = document.referrer.match(/^https?:\/\/([^:\/\s]+)\/?.*/);
      if (match) {
         var domain = match[0];
         for (var i=0; i < whitelist.length; i++) {
            if (domain == whitelist[i]) { return; }
         }
      }
      window.top.location = window.location;
   }
})();

Original post:

One problem it could still potentially solve is the issue of removing the bar once the user navigates away. Could we perhaps use it to communicate to the top frame that the user has navigated away to a new page?

Cheers,
Marcus

The iFrame is an important element in the HTML toolkit. However, while providing crucial functionality it also enables certain nuisances. http://www.meebo.com.br/ is a good example of iframe absue - the domain com.br iframes meebo.com and sticks a banner ad on top of it.

There is a well known solution to this problem - it is called frame busting:

<script type="text/javascript">

if (top.location != location) { top.location = location; }

</script>

However, this solution blindly busts out of all frames. What if you would want to allow for e.g. digg to iframe you, in order to allow for digg visitors to further digg your site and increase your traffic? It would look something like this:

<script type="text/javascript">

if ( ! top.location.domain.match(/digg.com$/) ) {

top.location = location;

}

</script>

This would effectively frame bust all sites but digg.com, were it not for the cross domain policy causing an error when you try to access top.location.domain or top.location.toString(), when top is on a different domain (toString gets called at any time you compare the location object to a string, e.g. top.location == “digg.com”).

oFrameBust is a protocol and an implementation designed to tackle this issue. The protocol works as follows:

Say digg.com wants to iframe¬†http://blog.narcvs.com/?p=55. I permit this, along with say facebook.com and marcuswestin.com, but I don’t want anyone else to iframe my site. On blog.narcvs.com, I just include the oframebust script and list the domains I want to allow:

<script type="text/javascript" src="http://oframebust.com/oframebust.js">

oFrameBust('digg.com', 'www.facebook.com', 'www.marcuswestin.com');

</script>

Then when digg wants to iframe me, they pass in the oframebust parameter declaring their domain:

http://blog.narcvs.com/?p=55&oframebust=digg.com

The oframebust script automatically detects the oframebust GET parameter, and uses it to create an iframe to http://digg.com/oframebust.html - since this page lives on the digg.com, it is allowed to read the top.location.hostname - if the top frame indeed is digg.com!

Now, there is the risk that the top framer is spoofing the digg.com domain. In order to protect from this, the oframebust script passes in the current page url to the oframebust.html page living on diggs domain:

http://digg.com/oframebust.html?http://blog.narcvs.com/?p=55

At this point, if the top frame was spoofing the digg.com domain, the digg.com oframebust page uses the url that was passed in in order to frame bust:

try {

top.location.hostname.toString()

} catch(e) {

top.location=decodeURIComponent(location.search.substr(1))

}

All together, the oframebust protocol is an open source, transparent solution to white listed frame busting! There is already an implementation in place: if you want to whitelist domains, just put

<script type="text/javascript" src="http://oframebust.com/oframebust.js">

oFrameBust('digg.com', 'facebook.com', 'www.facebook.com', 'marcuswestin.com');

</script>

on your site. Then all you’ve got to do is convince those websites to include the oframebust.html page on their domain.

That’s it! Let’s solve this problem as a community, shall we?