Skip to main content

XSS Hacks For Fun And Profit


Sometimes, just sometimes, I want to do something completely ludicrous with my web pages. For instance, just recently I wanted to embed dynamic, externally hosted content in a Blogger page, and I wanted to do it without having internal scroll bars. This meant sizing the iframe hosting the content to precisely fit the content within it, resizing it every time the content changed.

Told you it was ludicrous.

Anyway, I quickly ran into a few problems to do with cross-site scripting. Specifically, when a page is contained in an iframe within a page on a different domain, there are two things you can't do:

  1. It's impossible to size an iframe to its contents from the containing page
  2. It's impossible to size an iframe to its contents from inside the iframe

So how do I do it? Well, I use a mighty XSS hack! Give this a try:

Create a resizing widget

Create a blogger page called 'resize-widget' that contains the following code:

<script type="text/javascript">
<!-- 
      /**
       * This iframe gets load by the first iframe. This one
       * will communicate with the main page telling it to
       * resize the iframe that has content in it. It will
       * get the height from the URL that was used to
       * link to this page, e.g. iframe-resize.html?height=456
       */
        var params = window.location.search.substring( 1 ).split( '&' );
        var height;
        for( var i = 0, l = params.length; i < l; ++i ) {
          var parts = params[i].split( '=' );
          switch( parts[0] ) {
          case 'height':
            height = parseInt( parts[1] );
            break;
          }
        }
        if( typeof( height ) == 'number' ) {
          window.top.updateIFrame( height );
        }
//-->
</script>

What does it do? Not a lot. It pulls the request URL apart, finds a parameter named "height", and then calls a Javascript function on the topmost frame, passing the value of the height parameter as an argument.

Of course, it assumes that it is allowed to call functions on the topmost frame (i.e. it's on the same domain), and that the updateIFrame function exists. But assuming that is true, all is well.

Create the containing page

Next, create a page to contain your iframe to be resized. I will call mine iframe-resize-demo, although of course you can call it anything you like. Put this code in it:

<script type="text/javascript">
<!--
      /**
       * This function must be available on the main outer page.
       * When called with a height it will update the size of the
       * iframe to match that height.
       */
      function updateIFrame( height ) {

        var iframe = document.getElementById( 'myiframe' );
        var sidebar = document.getElementById( 'sidebar-wrapper' );
        iframe.setAttribute( 'height', Math.max(height, sidebar.scrollHeight) );

        var content = document.getElementById( 'content-wrapper' );
        document.body.scrollTop = Math.min(document.body.scrollTop, content.offsetTop);
      }
//-->
</script>

<iframe frameborder="0" height="150px" id="myiframe" scrolling="NO" src="http://my-nested-domain.com" width="100%"></iframe>

Aha! There's that updateIFrame function that takes a height as its parameter! What does it do? It updates the height of the iframe to match the height parameter. Actually it does a little more - it resizes it to the maximum of either the height parameter or the scrollHeight of the Blogger sidebar. It does this to ensure the Blogger template flows properly.

Create the dynamic, externally-hosted content

Of course, the external content can contain anything you like. But put this in it:

<script type="text/javascript">
<!--
/**
 * This function will update the URL on the inner iframe,
 * i.e. the iframe within an iframe.
 */
function resizeThisFrame() {
    var iframe = document.getElementById( 'inneriframe' );
    var wrapper = document.getElementById( 'wrapper' );
    var height = Math.max( document.body.offsetHeight, document.body.scrollHeigh
t );
    iframe.src = 'http://myblog.blogspot.com/p/resize-widget.html?height
='+height;
}
//-->
</script>

<body onload="resizeThisFrame()">
<iframe height="1px" width="1px" id="inneriframe" style="display: none;"></iframe>

What does it do? When the document body loads, it calculates the total height of the document, adds it to the URL of the resize-widget page we created a while back, and loads that URL into the iframe. This sets of a chain of events that culminates with the height parameter calculated here being passed into the updateIFrame function, and the iframe containing the page we've just written being expanded to fit!

Don't you feel dirty now?

Inspiration from Blog What I Made, and modified to work with Blogger.

Comments

Popular posts from this blog

Fairy Lights

Street lights at night can be very pretty. For someone who lives close to the centre of a large city, skirting round the edge of the town centre can provide a host of beautiful views at night. One advantage to using a wide open lens when taking these pictures is the capture of bokeh, or creative blur. An extreme example is shown to your right; a mass of coloured circles that roughly represent the city they are part of. A more subtle example, of course, is in the picture of the day at the top of this post. The lights cluster around the top of the leaves like fireflies, obviously part of a cityscape but at the same time abstract. The extreme out of focus image is a blurred version of the picture on the left. A view over Sheffield from Pitsmoor, looking up Netherthorpe Road and up to the university. Even when the buildings are focussed (roughly; I'm still practicing) the lights take on the shape of the lens's aperture. I try to incorporate some foreground focus wh...

In which I complain that coding standards are a waste of time

Just kidding. I'm not going to rail against coding standards. No, I'm going to rail against the absolute and dictatorial enforcement of coding style guidelines, to the point where a single misplaced curly bracket can fail the code review of a thousand line project before it's even started. I'm going to rail against the fact that many people these days don't actually know that coding style guidelines and coding standards are not the same thing. Coding style guidelines are not coding standards. Coding standards are rules on how to construct software. Rules that have practical and defined benefits. Rules than can be proven to assist in the structured and correct building of code. For example: Do not perform database access in the constructor. All database access should use the framework's DAL. Do not rely on complex instantiation instructions; provide a factory method. Do not inherit from a class in a different module or library; only encapsulate. Avoid sin...

DeCSS on Ubuntu 9.10 and later

It used to be the case that enabling DVD playback on Ubuntu was a case of installing ubuntu-restricted-extras and that was that. Unfortunately DMCA nonsense in the US has buggered that up for all of us and so now there's an additional step. So, without further ado, here are the commands that need to be run at a command line: sudo apt-get install libdvdread4 sudo /usr/share/doc/libdvdread4/install-css.sh Voila! DVD playback a-la Ubuntu.