框架巴斯特巴斯特…克星代码需要

假设您不希望其他网站在<iframe> “框架”您的网站:

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

所以你在你所有的页面中插入反框架的JavaScript代码:

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

优秀! 现在,你可以“自动”破解任何包含iframe的内容。 除了一个小问题。

事实certificate, 你的框架破解代码可以被破坏 , 如下所示 :

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

此代码执行以下操作:

  • 每当浏览器尝试通过window.onbeforeunload事件处理程序从当前页面导航离开时递增计数器
  • 设置一个通过setInterval()每毫秒触发的定时器,如果它看到计数器递增,则将当前位置更改为攻击者控制的服务器
  • 该服务器提供具有HTTP状态代码204的页面,这不会导致浏览器在任何地方导航

我的问题是 – 这更像是一个JavaScript谜题,而不是一个实际的问题 – 你怎么能打败这个破架破坏者?

我有几个想法,但没有在我的testing工作:

  • 试图通过onbeforeunload = null清除onbeforeunload事件没有效果
  • 添加一个alert()停止了这个过程,让用户知道它正在发生,但是并没有以任何方式干扰代码; 点击确定让破坏继续正常
  • 我想不出任何方法来清除setInterval()计时器

我不是一个JavaScript程序员,所以这里是我的挑战: 嘿,克星,你可以打破框架破坏?

我不确定这是否可行 – 但是如果你不能打破框架,为什么不显示一个警告。 例如,如果您的页面不是“首页”,请创build一个试图打破框架的setInterval方法。 如果在3或4次尝试后,你的网页仍然不是首页 – 创build一个div元素,覆盖整个页面(模式框)与一个消息和链接像…

您正在未经授权的框架窗口中查看此页面 – (Blah等等…潜在的安全问题)

点击这个链接来解决这个问题

不是最好的,但我不认为他们可以通过任何方式来解决这个问题。

想到这一点,似乎至less在Firefox和Opera浏览器工作。

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

我们在http://seclab.stanford.edu/websec/framebusting/framebust.pdf的网站中使用了以下方法;

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

经过一番思考,我相信这会告诉他们谁是老板…

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

使用_top作为window.open()的目标参数将在同一个窗口中启动它。

考虑到当前引入了针对iframe的沙箱的HTML5标准,当攻击者使用沙箱时,可以禁用此页面中提供的所有帧清除代码,因为它会限制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 

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

现在,考虑攻击者使用下面的代码在iframe中托pipe您的网站:

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

然后,所有的JavaScript框架破解代码将失败。

在检查所有帧总线代码之后,只有这种防御在所有情况下才起作用:

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

最初由Gustav Rydstedt,Elie Bursztein,Dan Boneh和Collin Jackson(2010)提出的,

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

好吧,所以我们知道这是在一个框架。 因此,我们将location.href作为另一个特殊页面,并将path作为GETvariables。 我们现在向用户解释发生了什么,并提供了一个与target =“_ TOP”选项的链接。 这很简单,可能会工作(没有testing过),但它需要一些用户的交互。 也许你可以指出这个网站给用户,并在你的网站上build立点击jackers的耻辱的大厅..只是一个想法,但它的夜晚工作..

所有提出的解决scheme直接强制改变顶窗的位置。 如果用户想要框架在那里呢? 例如search引擎的图像结果中的顶部框架。

我写了一个原型,默认情况下所有的input(链接,表单和input元素)被禁用和/或什么时候什么都不做。

如果检测到包含帧,input将被禁用,并在页面顶部显示警告消息。 警告消息包含一个链接,将在新窗口中打开安全版本的页面。 这可以防止页面被用于点击劫持,同时仍然允许用户在其他情况下查看内容。

如果未检测到包含帧,则启用input。

这是代码。 您需要将标准HTML属性设置为安全值,并添加包含实际值的附加属性。 这可能是不完整的,而对于完全安全的附加属性(我正在考虑事件处理程序)可能必须以相同的方式处理:

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

我要勇敢地把帽子扔进这个戒指(古代就是这样),看看我能收集多less收益。

这是我的尝试,似乎在我testing过的任何地方都能正常工作(Chrome20,IE8和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); }()); 

我将这段代码放在<head> ,并从<body>的最后调用它来确保我的页面在它开始与恶意代码争论之前被渲染,不知道这是否是最好的方法,YMMV。

它是如何工作的?

…我听到你问 – 诚实的答案是,我不知道。 在我testing的任何地方都花费了大量的时间和精力,根据运行地点的不同,确切的效果也会有所不同。

这是背后的思想:

  • 设置一个函数以尽可能最小的间隔运行。 我所看到的任何现实的解决scheme背后的基本概念是填补比框架破坏者有更多的事件调度。
  • 每次function触发时,尝试更改顶部框架的位置。 相当明显的要求。
  • 还要安排一个function立即运行,这将需要很长时间才能完成(从而阻止帧中断者干扰位置变化)。 我select了一个同步的XMLHttpRequest,因为它是我所能想到的唯一不需要(或者至less要求)用户交互的机制,并且不会咀嚼用户的CPU时间。

对于我的http://mysite.tld/page-that-takes-a-while-to-load (XHR的目标),我使用了一个如下所示的PHP脚本:

 <?php sleep(5); 

怎么了?

  • Chrome和Firefox在XHR完成时等待5秒钟,然后成功redirect到带框页面的URL。
  • IE立即redirect

你不能避免在Chrome和Firefox的等待时间?

显然不是。 起初,我将XHR指向一个可以返回404的URL – 这在Firefox中不起作用。 然后我尝试了sleep(5); 我最终着手解答这个问题,然后我开始以各种方式玩弄睡眠时间。 我没有发现真正的行为模式,但是我发现如果太短,特别是Firefox不会弹球(Chrome和IE似乎performance相当好)。 我不知道“太短”的定义是什么,但5秒似乎每次都有效。


如果任何传递的Javascript忍者想要更好地解释发生了什么,为什么这是(可能)错误,不可靠,他们见过的最差的代码等等,我会愉快地听。

截至2015年,您应该使用CSP2的frame-ancestors指令。 这是通过HTTP响应头来实现的。

例如

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

当然,很多浏览器都不支持CSP2,所以包含旧的X-Frame-Options头是明智X-Frame-Options

 X-Frame-Options: DENY 

我build议无论如何都要包括这两个方面,否则你的网站将继续容易受到旧浏览器中的点击劫持的攻击,当然,即使没有恶意的意图,你也会受到不良的诬陷。 现在,大多数浏览器都会自动更新,但是您仍然倾向于让公司用户因旧式应用程序兼容性原因而停留在旧版Internet Explorer中。

那么,你可以修改计数器的值,但这显然是一个脆弱的解决scheme。 你可以通过AJAX加载你的内容后,你已经确定该网站不在一个框架 – 也不是一个很好的解决scheme,但它希望避免发射beforeunload事件(我假设)。

编辑:另一个想法。 如果你发现你是在一个框架中,要求用户禁用JavaScript,然后点击一个链接,将你带到所需的URL(传递一个查询string,让你的网页知道告诉用户,他们可以重新启用JavaScript在那儿)。

编辑2:去核 – 如果你发现你在一个框架,只是删除你的文档正文内容,并打印一些讨厌的消息。

编辑3:你可以枚举顶部的文件,并设置为空(甚至匿名)的所有function?

我想你已经快到了。 你有没有尝试过:

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

或者,或者:

 window.parent.prevent_bust = 0; 

注意:我没有真正testing这个。

如果您在破坏者代码之后立即添加警报,则警报将阻止JavaScript线程,并且会让页面加载。 这就是StackOverflow所做的,即使在我使用框架破坏者的情况下,它也会从我的iframe中破解。 它也适用于我的简单testing页面。 这只在Firefox 3.5和IE7上testing过。

码:

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

反复打电话给那个人怎么样? 这将创造一个竞争条件,但有人可能会希望这个破坏者出现在最前面:

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

如果你看一下setInterval()返回的值,它们通常是单个数字,所以你通常可以用一行代码禁用所有这样的中断:

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

我可能只是刚刚得到了一个方式来破坏框架巴士克星。 在我的javascript函数中使用getElementsByName,我已经设置了一个帧解码器和实际的帧解码器脚本之间的循环。 检查这个post了。 http://www.phcityonweb.com/frame-buster-buster-buster-2426

setInterval和setTimeout创build一个自动递增的时间间隔。 每次调用setTimeout或setInterval时,这个数字都会上升一个,所以如果你调用setTimeout,你会得到当前最高的值。

  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"; } 

因为几乎没有人听说有10000个setIntervals和setTimeouts同时工作,并且由于setTimeout返回“last interval或timeout created +1”,并且由于top.clearInterval仍然可以访问,所以这会将黑帽攻击打败到帧上面描述的网站。

使用htaccess来避免高架框架,iframe和任何内容,如图像。

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

这将显示一个版权页,而不是预期的。

Interesting Posts