Frame Buster Buster … buster code needed

2018-12-31 02:42发布

Let's say you don't want other sites to "frame" your site in an <iframe>:

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

So you insert anti-framing, frame busting JavaScript into all your pages:

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

Excellent! Now you "bust" or break out of any containing iframe automatically. Except for one small problem.

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

<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:

  • increments a counter every time the browser attempts to navigate away from the current page, via the window.onbeforeunload event handler
  • sets up a timer that fires every millisecond via setInterval(), and if it sees the counter incremented, changes the current location to a server of the attacker's control
  • that server serves up a page with HTTP status code 204, which does not cause the browser to navigate anywhere

My question is -- and this is more of a JavaScript puzzle than an actual problem -- how can you defeat the frame-busting buster?

I had a few thoughts, but nothing worked in my testing:

  • attempting to clear the onbeforeunload event via onbeforeunload = null had no effect
  • adding an alert() stopped the process let the user know it was happening, but did not interfere with the code in any way; clicking OK lets the busting continue as normal
  • I can't think of any way to clear the setInterval() timer

I'm not much of a JavaScript programmer, so here's my challenge to you: hey buster, can you bust the frame-busting buster?

19条回答
闭嘴吧你
2楼-- · 2018-12-31 03:13

What about calling the buster repeatedly as well? This'll create a race condition, but one may hope that the buster comes out on top:

(function() {
    if(top !== self) {
        top.location.href = self.location.href;
        setTimeout(arguments.callee, 0);
    }
})();
查看更多
冷夜・残月
3楼-- · 2018-12-31 03:16

Use htaccess to avoid high-jacking frameset, iframe and any content like images.

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

This will show a copyright page instead of the expected.

查看更多
与君花间醉酒
4楼-- · 2018-12-31 03:17

After pondering this for a little while, I believe this will show them who's boss...

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

Using _top as the target parameter for window.open() will launch it in the same window.

查看更多
谁念西风独自凉
5楼-- · 2018-12-31 03:20

I think you were almost there. Have you tried:

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

or, alternatively:

window.parent.prevent_bust = 0;

Note: I didn't actually test this.

查看更多
伤终究还是伤i
6楼-- · 2018-12-31 03:21

Came up with this, and it seems to work at least in Firefox and the Opera browser.

if(top != self) {
 top.onbeforeunload = function() {};
 top.location.replace(self.location.href);
}
查看更多
临风纵饮
7楼-- · 2018-12-31 03:21

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

for (var j = 0 ; j < 256 ; ++j) clearInterval(j)
查看更多
登录 后发表回答