1.9.12

anti anti Frame Busting « coderrr

anti anti Frame Busting « coderrr

anti anti Frame Busting

Filed under: javascript, security — Tags: , — coderrr @ 4:21 pm
In this post I presented a way to prevent a site you were (i)framing from frame busting out. Jeff Atwood recently contacted me to see if I knew a way to get around the prevention (to prevent sites from framing stackoverflow.com), which of course I didn’t, but I told him I’d think about it and see if I could come up with something. A week later I had come up with a few ideas but none actually worked.

See updates below for latest/best solution

But, due to some extra motivation from his post today (which links to my original post), I may have just come up with something.
1if (top != self) {
2  top.location.replace(document.location)
3  alert('busting you out, please wait...')
4}  

It’s so stupid simple, but it seems to actually work. If you present an alert() box immediately after changing top.location you prevent the browser from running any more JS, either from your framed site or from the framing site. But you don’t prevent the browser from loading the new page. So as long as the alert box stays up for a few seconds until the browser has loaded enough of the new page to stop running scripts on the old page, then the anti frame busting code never runs and you successfully are busted out once the user clicks OK on the alert.

I’ve just done a preliminary test of this in FF3 and IE7 and it worked in both. So I’m calling it, anti-anti-frame-busting is here!

Update: Jason brought up in a comment the issue of a user clicking OK before the page finished loading in which case the anti-frame-bust will still prevent you from busting. One thing you can do to make sure that the page loads extremely quickly so that no user will be able to click OK before that is to (pre-)cache it. Here’s an example:

01<!-- this is the page being framed -->
02  <script>
03    function bust() {
04      if (top != self) {
05        // this page is now cached and will load immediately
06        top.location.replace("http://page-with-expires-headers.com/")
07        alert('busting you out, please wait...');
08      }
09    }
10  </script>
11  <!-- cache it! -->
12  

You should have these headers on the page to bust out with.


1Expires: Sun, 19 Aug 2012 14:10:44 GMT    <-- far enough in the future
2Last-modified: Fri, 19 Jun 2009 04:24:20 GMT    <-- now

First the framed page will do the initial load of the cached page in an iframe (which you can make hidden). Now that page will be cached and the next time you visit it the browser should make no network requests, loading the page completely from its local cache.

For this technique to work you’ll probly want to use it with a blank page which contains only a javascript/meta redirect to the actual page that was being framed. For example:


1<html><body>
2  redirecting...
3  <script> if (self == top) top.location='http://site-to-redirect-to.com/'; </script>
4</body></html>

Update: On IE7 this caching technique alone is good enough to prevent anti-frame-busting. Meaning no alert() is required after the top.location change. At least this is true for a simple page which only consists of a javascript redirect:

1<html>
2  <body>
3    we've busted out!  redirecting...
4    <script>
5      // only redirect if we're busted out
6      if (top == self)  top.location = "http://original-page.com";
7    </script>
8  </body>
9</html>

Update: The holy grail of anti-anti-frame-busting: This code, along with the caching technique described above, works in both FF3 and IE7 and has no negative user-experience (ie. alert boxes or frozen browsers):

1<script>
2  function bust() {
3    if (top != self)
4      setInterval("top.location.replace('http://cached-bust-out-page.com/with/redirect')",1);
5   }
6</script>
7<!-- cache it! -->

26 Comments »

  1. Wish I had the time and/or resources to test this, but I am intrigued. Having some blocking code run on the framed page, while the framing page finishes loading…
    But you are saying that the user has to wait a few moments before clicking “ok” for it to work? What about using a confirm() instead of an alert? That way we would have somewhat of a better mechanical turk, because perhaps users would be too quick to click “Ok.” Or maybe add a lot of text that they have to read first?
    Hmmm, interesting stuff. Perhaps when I come off of the cold medications I am on I will play with this stuff…
    Thanks for the info!
    Comment by Jason Bunting — June 18, 2009 @ 11:03 pm
  2. Thanks for the comment Jason, I updated the post with a technique which will mitigate this problem.
    I think using the caching technique we may even be able to get away with no alert and possibly just a blocking while loop or something. I need to do some more testing.
    Comment by coderrr — June 19, 2009 @ 4:28 am
    • A synchronized XMLHTTP request (blocking) to a page that sleep()s should do the trick.
      Comment by Godfrey Chan — June 19, 2009 @ 10:09 am
      • yes! I think that’s just what I was looking for, awesome! will test this in a second
        Comment by coderrr — June 19, 2009 @ 10:25 am
      • doh… doesn’t look like synchronous xmlhttprequests actually block timers (on FF, presumably IE as well) :/
        what’s next?
        Comment by coderrr — June 19, 2009 @ 10:47 am
      • ok so for IE (IE7 at least) you are correct, that did the trick and is just as effective as an alert, great find!
        Comment by coderrr — June 21, 2009 @ 11:08 am
  3. Nice. Again, I only partly know about this stuff, I was actually online at SO the moment Jeff originally posted his question and even gave it a few tries myself before giving up because I was already up late and needed to be done for the day. Hadn’t thought much about it until I saw Jeff’s blog entry about it.
    Funny, I thought about a while loop too…
    Hope this proves to be a solution, I look forward to the conclusion…
    :)
    Comment by Jason Bunting — June 19, 2009 @ 6:44 am
  4. [...] by Anti anti frame busting « coderrr — June 18, 2009 @ 4:22 pm [...]
    Pingback by Preventing Frame Busting and Click Jacking (UI Redressing) « coderrr — June 19, 2009 @ 7:46 am
  5. [...] @ 7:25 pm In my quest to find something which acts similar to an alert() box in Firefox 3 (for anti-anti-frame-busting), but without the annoying user-experience, I discovered a few things that I thought I should [...]
    Pingback by Firefox 3 internals, blocking alerts and XMLHttpRequests « coderrr — June 22, 2009 @ 7:25 pm
  6. First off I’d like to thank you for posting this. I originally read about this issue on Jeff’s site. At that time I thought that I’d book mark this link in case I’d ever run into this issue, although at the time I thought I would never need it. Turns out that one of our clients decided to frame our site so that he would have his logo on the page. That turned out to be a big no-no for compliance issues.
    Anyhow, I have a couple of questions about the holy grail method. I tried implementing this technique in .NET 3.5 with C#. The log-in page for the app contains an iframe that points to the log-in page. The src tag for the iframe contains a query string param that lets the log-in page in the iframe know that it should set the headers as specified so the page will not cache. I also have the version of the log-in page in the iframe contain no frame busting code.
    I would think that it this would allow me to not use a redirect page. The theory goes that the log-in page in the iframe is immediately cached by the browser. The parent log-in frame then contains the busting code as shown above.
    Anyhow, my attempt does not work. In IE 7/8 you can hear the navigation sound as the page tries to break out but the frame maintains the upper hand.
    My questions are this: What purpose does the redirect serve? It seems like the only reason you are using it is that it is cached and would load very, very quickly. Secondly, do you know of any server based attacks that would prevent the holy grail code? I can not find any script on the client’s frames. If there were script I could analyze what it’s doing and see if I could provide more info or perhaps a solution.
    Thanks,
    Mike
    Comment by Mike — July 22, 2009 @ 11:37 am
    • Hey Mike,
      You said “set the headers as specified so the page will not cache.”, did you mean to say so the page WILL cache?
      Yes, the only reason for the redirect is so you can bust with a page which loads extremely fast so that the parent page doesn’t have time to stop the bust.
      Even if you have the login page cached, if it has to load/render images, stylesheets, javascripts, etc. You would have to make sure all of those are cahced as well, and even then there will be time to render the page. It might be too slow.
      I’d say try it with a very simple redirect page. Also I’d be interested to see the site which is framing you.
      Comment by coderrr — July 23, 2009 @ 4:23 pm
      • Hey,
        Thanks for the reply. I kind of gave up on the whole thing for a bit because there was (and is) a bunch of stuff that we’re working on.
        I was making some compliance updates and SEO enhancements to our main website (the one listed). After I relisted with all the major search engines I saw that we had a bunch of backlinks that were all framed. I decided to revisit the issue and saw that I created a flaw in my code.
        I revisited my code and cleaned it up, saw the flaw and moved it our main site. It works like a charm. Thanks so much!
        Mike G.
        Comment by Mike — September 4, 2009 @ 4:31 pm
  7. Here’s my question is there a method where I can use the anti-frame buster code and put some type of javascript to trigger an event/submit inside of the said iframe?
    Comment by AC — March 24, 2010 @ 5:24 am
  8. [...] Anti-anti frame-busting [...]
    Pingback by Common Security Mistakes in Web Applications — October 18, 2010 @ 5:38 pm
  9. [...] Anti-anti frame-busting [...]
    Pingback by Design and Digital Media » Blog Archive » Common Security Mistakes in Web Applications — October 18, 2010 @ 8:22 pm
  10. [...] Anti-anti frame-busting [...]
    Pingback by Common Security Mistakes in Web Applications | LionWebMedia.com — October 19, 2010 @ 8:53 am
  11. [...] Anti-anti frame-busting [...]
    Pingback by Best and Cheap Solutions - Common Security Mistakes in Web Applications — October 27, 2010 @ 7:33 pm
  12. [...] Anti-anti frame-busting [...]
    Pingback by Common Security Mistakes in Web Applications « I.T News & Stuff — December 3, 2010 @ 4:47 am
  13. can u describe how u implement it on the site, i dont really get it.
    how is the file structure and which code where. Do i need to triger bust function ?
    Comment by Confuzed — May 6, 2011 @ 1:01 pm
  14. Can you please mail me the code source with .html extension in one folder.? I’m kinda confused.
    Comment by Mezzeric — May 24, 2011 @ 1:49 pm
  15. i have a solution that really works for anti frame break code if you want do me an offer for the code to the email netbizpt@gmail.com
    Comment by filipe — July 16, 2011 @ 5:20 pm
    • show me it in action!
      Comment by DemonTed1 — December 15, 2011 @ 6:03 am
  16. I found a much simpler way. Have the iframe on the top page call for a dummy page on your site. Then have the dummy page have another iframe calling for the site you want which is brekaking out. It will indeed break out of the dummy page, but because your dummy page is on your site, it will not break out of the first iframe. voilla
    Comment by Larry Holmes — January 5, 2012 @ 4:33 am

RSS feed for comments on this post. TrackBack URI