Frame Buster Buster... Need buster code

Keywords: Javascript Firefox IE Windows

Suppose you don't want other websites< iframe >Build your site:

<iframe src="http://example.org"></iframe>

Therefore, you will anti frame, frame damage JavaScript Insert into all your pages:

/* break us out of any containing iframes */
if (top != self) { top.location.replace(self.location.href); }

first-class! Now you automatically "crack" or break through any iframe that contains it. Except for a small problem.

It turns out that your frame breaking code can be broken, As shown below :

<script type="text/javascript">
    var prevent_bust = 0  
    window.onbeforeunload = function() { prevent_bust++ }  
    setInterval(function() {  
      if (prevent_bust > 0) {  
        prevent_bust -= 2  
        window.top.location = 'http://example.org/page-which-responds-with-204'  
      }  
    }, 1)  
</script>

This code does the following:

  • The counter is incremented every time the browser attempts to leave the current page through the window.onbeforeunload event handler
  • Set a timer to trigger every millisecond through setInterval(). If it sees the counter increasing, it will change the current location to the server controlled by the attacker
  • The server provides a page with HTTP status code 204, which does not cause the browser to navigate anywhere

My question is - it's more like a JavaScript puzzle than a practical one - how can you beat the framebreaker?

I had some ideas, but they didn't work in my tests:

  • Trying to clear the onbeforeunload event with onbeforeunload = null has no effect
  • Add an alert() to stop the process so that the user knows it is happening, but does not interfere with the code in any way; click OK to proceed normally
  • I can't think of any way to clear the setInterval() timer

I'm not a JavaScript programmer, so this is my challenge to you: Hey saboteur, can you sabotage the saboteur who sabotages the framework?

#1 building

I'm not sure it works - but if you can't break the framework, why don't you show a warning. For example, if your page is not the home page, create a setInterval method that attempts to break the frame. If your page is still not the home page after 3 or 4 attempts - create a div element that covers the entire page (modal box), with a message and a similar link

You are viewing this page in an unauthorized frame window - (Blah blah... Potential security issues)

Click this link to resolve this issue

Not the best, but I don't think they have any way to write their own.

#2 building

After a period of thinking, I believe it will tell them who is the boss

if(top != self) {
  window.open(location.href, '_top');
}

Using "top" as the target parameter of window.open() will launch it in the same window.

#3 building

All proposed solutions directly force the top window to change position. What if the user wants the framework there? For example, the top frame in the image results of a search engine.

I wrote a prototype in which all inputs (links, forms, and input elements) are disabled by default and / or do nothing when activated.

If an include frame is detected, the input is disabled and a warning message is displayed at the top of the page. The warning message contains a link that will open a secure version of the page in a new window. This prevents the page from being used for click hijacking while still allowing users to view content in other situations.

If no containing frames are detected, input is enabled.

This is the code. You need to set the standard HTML property to a safe value and add additional properties that contain the actual value. It may not be complete, and additional properties that are fully secure (I am considering event handlers) may have to be handled in the same way:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
  <head>
    <title></title>
    <script><!--
      function replaceAttributeValuesWithActualOnes( array, attributeName, actualValueAttributeName, additionalProcessor ) {
        for ( var elementIndex = 0; elementIndex < array.length; elementIndex += 1 ) {
          var element = array[ elementIndex ];
          var actualValue = element.getAttribute( actualValueAttributeName );
          if ( actualValue != null ) {
            element[ attributeName ] = actualValue;
          }

          if ( additionalProcessor != null ) {
            additionalProcessor( element );
          }
        }
      }

      function detectFraming() {
        if ( top != self ) {
          document.getElementById( "framingWarning" ).style.display = "block";
        } else {
          replaceAttributeValuesWithActualOnes( document.links, "href", "acme:href" );

          replaceAttributeValuesWithActualOnes( document.forms, "action", "acme:action", function ( form ) {
            replaceAttributeValuesWithActualOnes( form.elements, "disabled", "acme:disabled" );
          });
        }
      }
      // -->
    </script>
  </head>
  <body onload="detectFraming()">
    <div id="framingWarning" style="display: none; border-style: solid; border-width: 4px; border-color: #F00; padding: 6px; background-color: #FFF; color: #F00;">
      <div>
        <b>SECURITY WARNING</b>: Acme App is displayed inside another page.
        To make sure your data is safe this page has been disabled.<br>
        <a href="framing-detection.html" target="_blank" style="color: #090">Continue working safely in a new tab/window</a>
      </div>
    </div>
    <p>
      Content. <a href="#" acme:href="javascript:window.alert( 'Action performed' );">Do something</a>
    </p>
    <form name="acmeForm" action="#" acme:action="real-action.html">
      <p>Name: <input type="text" name="name" value="" disabled="disabled" acme:disabled=""></p>
      <p><input type="submit" name="save" value="Save" disabled="disabled" acme:disabled=""></p>
    </form>
  </body>
</html>

#4 building

if (top != self) {
  top.location.replace(location);
  location.replace("about:blank"); // want me framed? no way!
}

#5 building

If you add an alert after the buster code, the alert will stop the javascript thread and it will let the page load. This is the function of StackOverflow. Even if I use frame destroyer, it will disappear from my iframe. It also applies to my simple test page. This was only tested in Firefox 3.5 and IE7 on Windows 3.5.

Code:

<script type="text/javascript">
if (top != self){
  top.location.replace(self.location.href);
  alert("for security reasons bla bla bla");
}
</script>

#6 building

I will bravely put my hat on this ring (very old), and see how many feathers I can collect.

This is my attempt. It seems to work anywhere I test it (chrome 20, IE8 and FF14):

(function() {
    if (top == self) {
        return;
    }

    setInterval(function() {
        top.location.replace(document.location);
        setTimeout(function() {
            var xhr = new XMLHttpRequest();
            xhr.open(
                'get',
                'http://mysite.tld/page-that-takes-a-while-to-load',
                false
            );
            xhr.send(null);
        }, 0);
    }, 1);
}());

I put this code in < head > and call it from the end of < body > to make sure my page is presented before I start arguing with malicious code, I don't know if this is the best way, YMMV.

How does it work?

... I heard you ask - the honest answer is, I really don't know. It takes a lot of time to make it work anywhere I test, and its exact effect will vary slightly depending on where you run it.

Here's the idea behind it:

  • Set the function to run at the lowest possible interval. The basic concept behind any real-world solution I've seen is to populate the scheduler with more events than frame Buster buster.
  • Try changing the position of the top frame each time you activate this feature. The requirements are quite obvious.
  • At the same time, a function is scheduled to run immediately, which will take a long time to complete (thus preventing the frame breaker from blocking the position change). I chose a synchronous XMLHttpRequest because it's the only mechanism I can think of that doesn't require (or at least require) user interaction and doesn't take up user CPU time.

For my http://mysite.tld/page-that-takes-a-while-to-load (target of XHR), I used a PHP script as follows:

<?php sleep(5);

What's up?

  • When XHR completes, Chrome and Firefox wait five seconds, and then successfully redirect to the URL of the framed page.
  • IE redirect now

Can't you avoid waiting times for Chrome and Firefox?

Obviously not. Initially I pointed XHR to a URL that returned 404 - which doesn't work in Firefox. Then I tried sleep(5); I finally worked on the answer, and then I started playing sleep length in various ways. I can't find a real pattern of behavior, but I do find that if it's too short, especially Firefox won't play ball (Chrome and IE seem to be doing quite well). I don't know what the definition of "too short" actually is, but every five seconds seems to work.

If any delivery Javascript Ninja wants to better explain what's going on, why it's (probably) wrong, unreliable, the worst code they've ever seen, etc. I'll be happy to hear.

#7 building

We are http://seclab.stanford.edu/websec/framebusting /The following methods are used in a website on frameboost.pdf.

<style>
 body { 
 display : none   
}
</style>
<script>
if(self == top) {
document.getElementsByTagName("body")[0].style.display = 'block';
}
else{
top.location = self.location;
}
</script>

#8 building

Considering the current HTML5 standard for sandboxing iframe, when an attacker uses sandboxing, he can disable all frame breaking code provided in this page because it limits the following iframe:

allow-forms: Allow form submissions.
allow-popups: Allow opening popup windows.
allow-pointer-lock: Allow access to pointer movement and pointer lock.
allow-same-origin: Allow access to DOM objects when the iframe loaded form same origin
allow-scripts: Allow executing scripts inside iframe
allow-top-navigation: Allow navigation to top level window

Please refer to: http : //www.whatwg.org/specs/web-apps/current-work/multipage/the-if​​rame-element.html#attr-iframe-sandbox

Now consider an attacker using the following code to host your site in iframe:

<iframe src="URI" sandbox></iframe>

Then, all JavaScript frame breaking code will fail.

After checking all frame bus codes, only this defense applies in all cases:

<style id="antiClickjack">body{display:none !important;}</style>
<script type="text/javascript">
   if (self === top) {
       var antiClickjack = document.getElementById("antiClickjack");
       antiClickjack.parentNode.removeChild(antiClickjack);
   } else {
       top.location = self.location;
   }
</script>

Originally from Proposed by Gustav Rydstedt, Elie Bursztein, Dan Boneh and Collin Jackson (2010)

#9 building

setInterval and setTimeout create an auto increment interval. Each time you call setTimeout or setInterval, the number increases by 1, so if you call setTimeout, you get the current maximum value.

   var currentInterval = 10000;
   currentInterval += setTimeout( gotoHREF, 100 );
   for( var i = 0; i < currentInterval; i++ ) top.clearInterval( i );
   // Include setTimeout to avoid recursive functions.
   for( i = 0; i < currentInterval; i++ )     top.clearTimeout( i );

   function gotoHREF(){
           top.location.href = "http://your.url.here";
   }

Because it is almost unheard of that 10000 concurrent setIntervals and settimeouts work, and because setTimeout returns "last interval or created timeout + 1", and because top.clearInterval is still accessible, this will defeat the black box attack on the website described above.

#10 building

Using htaccess avoids high-level framesets, iframe s, and anything, such as images.

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^http://www\.yoursite\.com/ [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteRule ^(.*)$ /copyrights.html [L]

This will display the copyright page instead of what is expected.

#11 building

If you look at the values returned by setInterval(), they are usually a single number, so you can usually disable all such interrupts with one line of code:

for (var j = 0 ; j < 256 ; ++j) clearInterval(j)

#12 building

FWIW, most current browsers Support X-Frame-Options: deny Instruction, which can be used even if the script is disabled.

IE8:
http://blogs.msdn.com/ie/archive/2009/01/27/ie8-security-part-vii-clickjacking-defenses.aspx

Firefox (3.6.9)
https://bugzilla.mozilla.org/show_bug.cgi?id=475530
https://developer.mozilla.org/en/The_X-FRAME-OPTIONS_response_header

Chrome / Webkit
http://blog.chromium.org/2010/01/security-in-depth-new-security-features.html
http://trac.webkit.org/changeset/42333

#13 building

As of 2015, you should use CSP2's frame-ancestors Instructions. This is done through the HTTP response header.

for example

Content-Security-Policy: frame-ancestors 'none'

Of course, not many browsers support CSP2, so the old X-Frame-Options Headers are wise:

X-Frame-Options: DENY

In any case, I recommend including both, otherwise your site will continue to be vulnerable to the Clickjacking Attack, of course, even if there is no malice, you will get an unwelcome framework. Most browsers will update automatically recently, but for legacy application compatibility reasons, you still tend to have enterprise users on older versions of Internet Explorer.

#14 building

I may have just found a way to break the framework breaker's program. Using getElementsByName in my javascript function, I set up a loop between frame buster and the actual frame Buster script. Look at this article. http://www.phcityonweb.com/frame-buster-buster-buster-2426

#15 building

Well, you can change the value of the counter, but this is clearly a fragile solution. After making sure that the site is not within the framework, you can load content through AJAX - which is not a good solution either, but it is expected to avoid triggering the on beforeload event (I assume).

Editor: another idea. If you detect that you are in a framework, ask the user to disable javascript, and then click a link to take you to the desired URL (pass a query string so your page knows to tell the user that they can re enable javascript once they are there).

Editor 2: de check - if you find yourself in a frame, just delete the body of your document and print some annoying messages.

Edit 3: can you enumerate top-level documents and set all functions to null (even anonymous functions)?

#16 building

I think you're almost there. Have you tried:

window.parent.onbeforeunload = null;
window.parent.location.replace(self.location.href);

Or:

window.parent.prevent_bust = 0;

Note: I haven't actually tested this.

#17 building

With that in mind, it seems to work at least in Firefox and Opera browsers.

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

#18 building

How to call the destroyer again and again? This will create a competitive environment, but one may want this destroyer to be at the forefront:

(function() {
    if(top !== self) {
        top.location.href = self.location.href;
        setTimeout(arguments.callee, 0);
    }
})();

#19 building

OK, so we know it's a framework. So we change the location.href to another special page, with the path as the GET variable. We now explain to the user what happened and provide a link with the option "target =". It's simple and may work (not tested), but it requires some user interaction. Maybe you can point out the offending website to users, and make a hall of humiliating click jackets for your website somewhere... It's just an idea, but it works at night

Published 0 original articles, won praise 2, visited 9074
Private letter follow

Posted by spiceydog on Sun, 02 Feb 2020 22:22:15 -0800