coderrr

February 13, 2009

Preventing Frame Busting and Click Jacking (UI Redressing)

Filed under: javascript, security — Tags: , — coderrr @ 2:05 am

Shameless Plug: Don’t let your clicks be tracked. Protect your browsing habits with a VPN Service.

Some websites are under the impression this very old frame busting code can prevent click jacking attacks:

try {
  if (top.location.hostname != self.location.hostname) throw 1;
} catch (e) {
  top.location.href = self.location.href;
}

Here’s a very simple way around this which works in both FF and IE7: (update, a way to work around this prevetion here)

  var prevent_bust = 0
  window.onbeforeunload = function() { prevent_bust++ }
  setInterval(function() {
    if (prevent_bust > 0) {
      prevent_bust -= 2
      window.top.location = 'http://server-which-responds-with-204.com'
    }
  }, 1)

The server only needs to respond with:

HTTP/1.1 204 No Content

On most browsers a 204 (No Content) HTTP response will do nothing, meaning it will leave you on the current page. But the request attempt will override the previous frame busting attempt, rendering it useless. If the server responds quickly this will be almost invisible to the user.

Update: If the frame busting code is at the beginning of the page, before any content loads, then even though the frame busting will be prevented, so will the loading of the remainder of the page. This means that your content would be hidden and un-clickjackable (only in FF, see below for IE).

So what can a website do to prevent clickjacking? I’m not a security expert but this seems to cover almost all the cases:

First, have your page load with all content hidden using CSS. Something along the lines of:

<body style="display:none" ...>

Then use some variant of the frame busting code, but instead of busting, use it to determine whether or not to display your content:

try {
  if (top.location.hostname != self.location.hostname)
    throw 1;

  document.body.style.display = 'block';
} catch (e) {
  // possible clickjack attack, leave content hidden
}

This covers most of the cases. It covers IE’s SECURITY=RESTRICTED which allows you to turn off scripting for an iframe. If your site is loaded like this, your script will not run and your content will remain hidden (as mentioned here). And it covers a standard clickjack attack by not displaying your content if it detects that it has been framed. What it doesn’t cover is a user who comes to your site with javascript disabled (who will see nothing). You of course could present them with a message saying javascript is required (using <noscript>). Sucks, but it seems at this point that is the price to pay for clickjacking protection.

If you have or know of a better solution please let me know.

Note to users: NoScript can protect you from clicking on invisible elements.

56 Comments »

  1. If you’re talking about twitter, they’ve just fixed this. Content is now hidden in the iframe.

    Comment by Wesley — February 13, 2009 @ 9:17 am

  2. Cool, looks like they’re still vuln for ppl w/o JS, but that’s probly an acceptably small %.

    Comment by coderrr — February 13, 2009 @ 9:48 am

  3. interesting article… I like very much the idea of display:none, although would drive off visitors. Not because of turned off javascript (only), but think of a user with noscript. If he doesn’t see the website he won’t know it’s because javascript being turned off…

    Comment by dblackshell — February 21, 2009 @ 9:54 am

  4. Yea I agree it sucks… It just doesn’t seem like there is any other solution for websites to prevent click jacking against users with JS turned off (and w/o noscript).

    If you are using NoScript won’t it display content inside of <noscript> tags?

    Comment by coderrr — February 21, 2009 @ 10:05 am

  5. if you use NoScript, noscript tags are shown when no Javascript is allowed… exactly as it would happen if you would have javascript disabled

    Comment by dblackshell — February 22, 2009 @ 10:55 pm

  6. so then that takes care of the problem you mentioned above right? You could use <noscript> to tell the visitor why they aren’t seeing the website.

    Comment by coderrr — February 23, 2009 @ 2:10 am

  7. you hide the entire body, the noscript tag is inside the body… how would you like to inform the user?

    maybe using a css rule

    noscript { display: block; }

    would solve the problem… don’t know didn’t have the mood to test it :P

    Comment by dblackshell — February 23, 2009 @ 5:29 am

  8. Oh yea, very good point! I tried the css example you suggested and it wouldn’t show the noscript tag if it was inside a hidden body. So it seems instead of hiding the whole body you’d have to make sure you have a div around everything except the noscript tag and then hide that div.

    Comment by coderrr — February 23, 2009 @ 7:43 am

  9. the best bet would be to add the css rule display:none to the #wrapper selector… I say #wrapper because it’s an identifier generally used to wrap the header/content/footer…

    and after that wrapper add the noscript tag with the info.

    Comment by dblackshell — February 23, 2009 @ 11:45 am

  10. yea that sounds good

    Comment by coderrr — February 23, 2009 @ 11:48 am

  11. It is all click jacking and we might see more such attacks in future.

    The quickest fix for this attack is – DO NOT let your site be loaded in an iframe. Thats it!

    if (window.parent.frames.length>0) {
    //you are framed.
    //Go to your site without frame window.parent.location=location;
    }

    Comment by web — February 24, 2009 @ 2:21 pm

  12. Did you read the post?

    It is important you specify that this fix be put at the TOP of the page, before any content is loaded. Otherwise, as I showed in my post, I can block your framebusting attempt.

    Also your fix won’t work when someone iframes you in an IE restricted frame or if the user has JS disabled.

    Comment by coderrr — February 24, 2009 @ 2:27 pm

  13. [...] the SECURITY=restricted iframe attribute under IE and by using the methods that coderr mentioned in this article. For users NoScript is the right protection, until (who knows) browsers do something [...]

    Pingback by 1-2-3-Clickjacking — February 26, 2009 @ 7:02 am

  14. Wait a second. If a user has JS turned off, a clickjacking attempt would be pointless since the attack relies on JS.

    Comment by Nikola — February 27, 2009 @ 10:38 am

  15. Nikola,

    No actually clickjacking can be achieved with only css.

    All you need is transparency, positioning, and z-index ordering.

    Comment by coderrr — February 27, 2009 @ 10:46 am

  16. Working anti-buster-buster-buster code here:

    http://stackoverflow.com/questions/958997/frame-buster-buster-buster-code-needed

    CHECK.. YOUR MOVE SIRS!!

    – edit –

    For the benefit of comment readers, the above code does not work. – coderrr

    Comment by Jeff Atwood — June 6, 2009 @ 5:21 am

  17. [...] Filed under: javascript, security — Tags: javascript, security — 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 [...]

    Pingback by Anti anti frame busting « coderrr — June 18, 2009 @ 4:22 pm

  18. [...] I’ll tell you what happens. This happens. [...]

    Pingback by We Done Been … Framed! | Design Website — June 19, 2009 @ 12:54 pm

  19. [...] the SECURITY=restricted iframe attribute under IE and by using the methods that coderr mentioned in this article. For users NoScript is the right protection, until (who knows) browsers do something [...]

    Pingback by insanesecurity — June 24, 2009 @ 4:52 pm

  20. [...] I’ll tell you what happens. This happens. [...]

    Pingback by We Done Been … Framed! | PHP Hosts — August 6, 2009 @ 7:09 am

  21. Using the re-direct method will get your page banned by Google! They ban all pages which re-direct a user to another page, all SE’s do, don’t they?

    Comment by texxs — August 26, 2009 @ 5:21 pm

  22. display: block means that the element is displayed as a block, as paragraphs and headers have always been.

    maybe you mean to display: none ?

    Comment by Joseph Smith — September 17, 2009 @ 4:17 pm

    • no, the body starts out ‘none’ and then is changed to ‘block’ only if the site is not framed

      Comment by coderrr — September 17, 2009 @ 4:34 pm

  23. I don’t get it. I haven been playing with it but it just get screwed up.

    Let say I put http://abc.com which has a framekiller inside an , and then I put you iframekiller Killer
    in the section, I noticed the browser will just keep looking for
    http://server-which-responds-with-204.com or if I change that to anything else, it will still look for it. I even created an empty blog using blogger with nothing in the header or body, it just display the empty blog instead of the iframe page at whatever.com/whatever.html

    Am I missing something here? What exatly do I need to do for window.top.location = ‘http://server-which-responds-with-204.com’

    Any help is appreciated.

    Thanks.

    Comment by Mr X — December 4, 2009 @ 12:23 pm

    • Some of the message has been stripped off … I meant to say I wrap your code using javascript tag and put in the HEAD section.

      Comment by Mr X — December 4, 2009 @ 12:27 pm

      • Okay I finally found out how to do HTTP/1.1 204 No Content but I have no clue how the rest works.

        Right now, the framebusting stops, and then if I do body style=”display:none” then nothings shows up, so where do I put the last one? It doesn’t seem to do a thing?

        Comment by Mr X — December 4, 2009 @ 2:19 pm

  24. How about this:

    window.onbeforeunload = function() {};
    if (top.location.hostname != self.location.hostname)
    top.location.href = self.location.href;

    Comment by originalgeek — May 25, 2010 @ 7:01 pm

  25. Clickjacking – Framebuster oder HTTP-Header verhindern Angriffe…

    Wie Clickjacking allgemein funktioniert und welche Möglichkeiten es einem Angreifer bietet, haben Sie in den ersten beiden Folgen erfahren. Jetzt geht es um die Möglichkeiten, einen Clickjacking-Angriff zu verhindern bzw. abzuwehren….

    Trackback by Dipl.-Inform. Carsten Eilers — May 27, 2010 @ 7:12 am

  26. Pretty interesting, I had never even heard of click jacking until now :/

    Comment by William — July 5, 2010 @ 5:27 am

  27. [...] HomeArchivosContáctenosPatrocinarWP-SWFObjectWP-TweetButtonDevPlanetForum google_ad_client="pub-2072389614652287";google_ad_slot="4314051166";google_ad_width=728;google_ad_height=90; Prevenir el clickjacking con Javascript22 August 2010 | 0 comentarios | General, HTML, Javascript, SeguridadTags: clickjacking, frame, iframe, seguridad google_ad_client="pub-2072389614652287";google_ad_slot="4108947109";google_ad_width=336;google_ad_height=280; Prevenir el clickjacking consiste en evitar que nuestra página sea cargada dentro de otra mediante un frame o iframe, esto para prevenir el robo de contenido así como evitar el uso de nuestra página para forzar a los visitantes a realizar clicks maliciosos. Entonces el objetivo es evitar que nuestra página pueda ser cargada dentro de otra utilizando frames o iframes.Que es Clickjacking?El clickjacking consiste en cargar una página dentro de otra utilizando un iframe y sobre ella mostrar otra página oculta con transparencia, de forma tal que si hacemos click en un botón para buscar estaremos indirectamente haciendo click sobre otra página para propósitos maliciosos.Prevenir Clickjacking – Primer MétodoLa idea básica para prevenir que nuestra página sea cargada dentro de otra con frames o iframes es verificar la propiedad location del frame actual es igual al del frame superior. Si no son iguales estas propiedades es síntoma que nuestra página se esta cargando dentro de otra por lo tanto redireccionamos al url de nuestra web.<script type="text/javascript">if (top.location != location) top.location = self.location;</script>El método anterior por lo general es suficiente en la mayoría de los casos, pero existen técnicas para saltarse esta verificación, por ejemplo utilizar iframes anidados o generar errores de Javascript con lo cual se detiene cualquier verificación con javascript adicional. En el artículo Busting frame busting: a study of clickjacking vulnerabilities at popular sites se explica las múltiples formas de evitar el Frame Busting.Prevenir Clickjacking – Segundo MétodoUna forma sencilla de prevenir el uso de nuestras páginas en otros sitios es primero ocultar todo el contenido de nuestra web utilizando estilos. Luego de ello verificamos si la propiedad location del frame actual y el superior son iguales en cuyo caso volvemos visible todo el contenido de nuestro web en caso contrario redireccionamos a nuestra url.<style type="text/css"> body { display:none; } </style><script type="text/javascript">if (self == top) {   document.getElementsByTagName("body")[0].style.display = 'block';} else {   top.location = self.location;}</script>De esta forma si el atacante de alguna forma genera un error de javascript o utiliza frames anidados solo se mostrará una página en blanco, una validación sencilla pero muy eficiente para evitar que nuestra web sea utilizada por terceros.Mas InformaciónBusting frame busting: a study of clickjacking vulnerabilities at popular sitesDefeating Frame Busting TechniquesPreventing Frame Busting and Click Jacking (UI Redressing) [...]

    Pingback by Prevenir el clickjacking con Javascript | unijimpe — August 22, 2010 @ 9:21 pm

  28. [...] to an iframe will stop any frame busting code from working in Internet Explorer, and there are ways to prevent frame busting in Firefox as [...]

    Pingback by Common Security Mistakes in Web Applications |  — October 18, 2010 @ 1:22 pm

  29. [...] to an iframe will stop any frame busting code from working in Internet Explorer, and there are ways to prevent frame busting in Firefox as well. A better way might be to make your submit button [...]

    Pingback by Common Security Mistakes in Web Applications — October 18, 2010 @ 5:37 pm

  30. [...] to an iframe will stop any frame busting code from working in Internet Explorer, and there are ways to prevent frame busting in Firefox as [...]

    Pingback by Design and Digital Media » Blog Archive » Common Security Mistakes in Web Applications — October 18, 2010 @ 8:21 pm

  31. [...] to an iframe will stop any frame busting code from working in Internet Explorer, and there are ways to prevent frame busting in Firefox as [...]

    Pingback by Common Security Mistakes in Web Applications | LionWebMedia.com — October 19, 2010 @ 8:52 am

  32. [...] to an iframe will stop any frame busting code from working in Internet Explorer, and there are ways to prevent frame busting in Firefox as [...]

    Pingback by Common Security Mistakes in Web Applications | Web Design Course Brisbane: Next Course Wed 20th Oct 2010 — October 20, 2010 @ 7:46 am

  33. [...] to an iframe will stop any frame busting code from working in Internet Explorer, and there are ways to prevent frame busting in Firefox as [...]

    Pingback by Best and Cheap Solutions - Common Security Mistakes in Web Applications — October 27, 2010 @ 7:33 pm

  34. Instead of hiding body, we can hide forms.
    <head>
    <style>
    form {display:none;}
    </style>
    </head>
    and if its safe, only then to show forms, and include noscript notice info next to forms.
    will it be safe?

    Comment by Atul Gupta — November 16, 2010 @ 4:22 am

  35. [...] to an iframe will stop any frame busting code from working in Internet Explorer, and there are ways to prevent frame busting in Firefox as [...]

    Pingback by Common Security Mistakes in Web Applications « I.T News & Stuff — December 3, 2010 @ 4:46 am

  36. This is a very good article but can anyone tell me how can I test click jacking for my local application

    thanks in advance

    Comment by Atish — December 30, 2010 @ 10:31 am

  37. There are always going to be hacks that work around any type of defense, if you code using server-side languages you can load an external websites html and then change it and send it to the client.

    AJAX is growing in poularity and could achieve this.

    Comment by Web Developer — February 13, 2011 @ 11:15 am

  38. To allow refreshing the site itself by using

    would this work?

    if (top.location.hostname != self.location.hostname) {
    window.top.location = ‘http://server-which-responds-with-204.com’;
    } // if

    Comment by Michael — March 3, 2011 @ 7:29 am

  39. Hi!

    I only have one doubt, how the 204 http status work????????

    Thanks for the help.

    Comment by gvargas — March 3, 2011 @ 10:56 pm

  40. [...] to an iframe will stop any frame busting code from working in Internet Explorer, and there are ways to prevent frame busting in Firefox as well.A better way might be to make your submit button [...]

    Pingback by Common Security Mistakes in Web Applications : Copy & Print Center — April 25, 2011 @ 2:26 pm

  41. [...] to an iframe will stop any frame busting code from working in Internet Explorer, and there are ways to prevent frame busting in Firefox as [...]

    Pingback by Common Security Mistakes in Web Applications | The Dynamic Way — June 1, 2011 @ 11:49 am

  42. [...] As it turns out, your frame-busting code can be busted, as shown here: [...]

    Pingback by Frame Buster Buster … buster code needed — September 28, 2011 @ 12:24 pm

  43. [...] As it turns out, your frame-busting code can be busted, as shown here: [...]

    Pingback by Can you beat a frame breaker? | SeekPHP.com — October 26, 2011 @ 4:11 am

  44. What if we have hidden the content using css {display: none} and i have SECURITY=RESTRICTED in IE the script wont run and blank page will be shown to user. Can’t the frame which loaded this cant access this body and toggle it to block ?

    Comment by techmadememad — December 5, 2012 @ 7:29 pm

  45. [...] to an iframe will stop any frame busting code from working in Internet Explorer, and there are ways to prevent frame busting in Firefox as [...]

    Pingback by Common Security Mistakes in Web Applications - Goodfav Howto — March 4, 2013 @ 2:32 pm

  46. if (prevent_bust > 0) {
    prevent_bust -= 2
    window.top.location = ‘#’
    }

    Comment by Anonymous — March 6, 2013 @ 12:05 am

  47. [...] Some will replace the window.top.location with page responds with 204 No Content status (read here). Maybe you can add cookie as a flag. Here is a sample [...]

    Pingback by JavaScript: Framebuster busterElan Marikit | Elan Marikit — March 7, 2013 @ 2:13 pm

  48. Hi,

    does the Anti-Frame-Buster Code from the initial article work with the following Frame-Busting Code?

    if(window != parent)
    {
    document.topredirect.submit();
    }

    Comment by Lutz — April 10, 2013 @ 9:21 pm

  49. […] I know that we could use the solution from coderr but I’m not sure what the implications / knock on issues are. Given that we have access to […]

    Pingback by Preventing frame busting with access to page source - Tech Forum Network — June 14, 2013 @ 5:54 pm

  50. […] Some will replace the window.top.location with page responds with 204 No Content status (read here). Maybe you can add cookie as a flag. Here is a sample […]

    Pingback by JavaScript: Framebuster buster | Elan Marikit — July 4, 2013 @ 1:51 pm

  51. […] As it turns out, your frame-busting code can be busted, as shown here: […]

    Pingback by Frame Buster Buster … buster code needed | Think Aspx — August 8, 2013 @ 11:07 pm

  52. […] As it turns out, your frame-busting code can be busted, as shown here: […]

    Pingback by Frame Buster Buster … buster code needed | Ask & Answers — October 31, 2013 @ 9:28 am


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Customized Silver is the New Black Theme Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 28 other followers

%d bloggers like this: