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:
你在所有的页面中插入反框架,框架破坏JavaScript:
/* 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.
太好了!现在你“崩溃”或自动跳出任何包含iframe。除了一个小问题。
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 - 每当浏览器试图通过窗口从当前页面导航时,增加一个计数器。onbeforeunload事件处理程序
- 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 - 设置一个计时器,通过setInterval()每毫秒触发一次,如果看到计数器递增,则将当前位置更改为攻击者控制的服务器
- that server serves up a page with HTTP status code 204, which does not cause the browser to navigate anywhere
- 该服务器提供一个带有HTTP状态代码204的页面,这不会导致浏览器在任何地方导航
My question is -- and this is more of a JavaScript puzzle than an actual problem -- how can you defeat the frame-busting buster?
我的问题是——这更多的是一个JavaScript难题,而不是一个实际的问题——你如何才能打败这个破坏框架的家伙?
I had a few thoughts, but nothing worked in my testing:
我有一些想法,但在我的测试中什么都没有成功:
- attempting to clear the
onbeforeunload
event viaonbeforeunload = null
had no effect - 尝试通过onbeforeunload = null清除onbeforeunload事件没有任何效果
- 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 - 添加一个alert()停止了进程,让用户知道它正在发生,但不以任何方式干扰代码;点击OK让崩溃照常继续
- I can't think of any way to clear the
setInterval()
timer - 我想不出任何清除setInterval()计时器的方法
I'm not much of a JavaScript programmer, so here's my challenge to you: hey buster, can you bust the frame-busting buster?
我不是什么JavaScript程序员,所以我对你的挑战是:嘿,伙计,你能不能破毁框架?
19 个解决方案
#1
139
I'm not sure if this is viable or not - but if you can't break the frame, why not just display a warning. For example, If your page isn't the "top page" create a setInterval method that tries to break the frame. If after 3 or 4 tries your page still isn't the top page - create a div element that covers the whole page (modal box) with a message and a link like...
我不确定这是否可行,但如果你不能打破框架,为什么不显示一个警告。例如,如果您的页面不是“顶部页面”,那么创建一个试图破坏框架的setInterval方法。如果在3或4次尝试之后,你的页面仍然不是顶部页面——创建一个div元素,包含整个页面(模态框),其中包含一条消息和一个链接,比如……
You are viewing this page in a unauthorized frame window - (Blah blah... potential security issue)
你正在一个未经授权的框架窗口中查看这个页面。潜在的安全问题)
click this link to fix this problem
单击此链接可解决此问题。
Not the best, but I don't see any way they could script their way out of that.
不是最好的,但我看不出他们有什么办法来摆脱它。
#2
199
FWIW, most current browsers support the X-Frame-Options: deny directive, which works even when script is disabled.
FWIW是目前大多数浏览器都支持X-Frame-Options: deny指令,即使禁用了脚本,它也能工作。
IE8:
http://blogs.msdn.com/ie/archive/2009/01/27/ie8-security-part-vii-clickjacking-defenses.aspx
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
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
Chrome / Webkit http://blog.chromium.org/2010/01/security-in-depth-new-security-features.html http://trac.webkit.org/changeset/42333
#3
29
We have used the following approach in one of our websites from http://seclab.stanford.edu/websec/framebusting/framebust.pdf
我们在一个网站上使用了以下方法: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>
#4
29
Came up with this, and it seems to work at least in Firefox and the Opera browser.
这个想法出现了,至少在Firefox和Opera浏览器中是可行的。
if(top != self) {
top.onbeforeunload = function() {};
top.location.replace(self.location.href);
}
#5
19
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.
使用_top作为windows .open()的目标参数将在同一个窗口中启动它。
#6
19
Considering current HTML5 standard that introduced sandbox for iframe, all frame busting codes that provided in this page can be disabled when attacker uses sandbox because it restricts the iframe from following:
考虑到目前为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
Please see: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-iframe-element.html#attr-iframe-sandbox
请参见:http://www.whatwg.org/specs/web-apps/current-work/multipage/the-iframe-element.html # attr-iframe-sandbox
Now, consider attacker used the following code to host your site in iframe:
现在,考虑攻击者使用以下代码在iframe中托管您的站点:
<iframe src="URI" sandbox></iframe>
Then, all JavaScript frame busting code will fail.
然后,所有的JavaScript框架破坏代码都将失败。
After checking all frame busing code, only this defense works 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>
that originally proposed by Gustav Rydstedt, Elie Bursztein, Dan Boneh, and Collin Jackson (2010)
最初由Gustav Rydstedt, Elie Bursztein, Dan Boneh和Collin Jackson提出(2010)
#7
6
if (top != self) {
top.location.replace(location);
location.replace("about:blank"); // want me framed? no way!
}
#8
5
Ok, so we know that were in a frame. So we location.href to another special page with the path as a GET variable. We now explain to the user what is going on and provide a link with a target="_TOP" option. It's simple and would probably work (haven't tested it), but it requires some user interaction. Maybe you could point out the offending site to the user and make a hall of shame of click jackers to your site somewhere.. Just an idea, but it night work..
我们知道这是在一个坐标系中。所以我们的位置。href到另一个特殊页面,路径为GET变量。我们现在向用户解释发生了什么,并提供一个带有target="_TOP"选项的链接。它很简单,很可能会工作(还没有测试过),但是它需要一些用户交互。也许你可以向用户指出这个冒犯你的网站,并让那些点击你网站的人感到羞愧。只是一个想法,但它是夜间工作。
#9
5
All the proposed solutions directly force a change in the location of the top window. What if a user wants the frame to be there? For example the top frame in the image results of search engines.
所有提议的解决方案都直接强制改变顶部窗口的位置。如果用户希望帧在那里呢?例如,搜索引擎图像结果的顶部框架。
I wrote a prototype where by default all inputs (links, forms and input elements) are disabled and/or do nothing when activated.
我编写了一个原型,在默认情况下,所有输入(链接、表单和输入元素)都被禁用,或者在激活时什么都不做。
If a containing frame is detected, the inputs are left disabled and a warning message is shown at the top of the page. The warning message contains a link that will open a safe version of the page in a new window. This prevents the page from being used for clickjacking, while still allowing the user to view the contents in other situations.
如果检测到包含的帧,则将禁用输入,并在页面顶部显示一条警告消息。警告消息包含一个链接,该链接将在新窗口中打开页面的安全版本。这阻止了页面被用于点击,同时仍然允许用户在其他情况下查看内容。
If no containing frame is detected, the inputs are enabled.
如果没有检测到包含帧,则启用输入。
Here is the code. You need to set the standard HTML attributes to safe values and add additonal attributes that contain the actual values. It probably is incomplete and for full safety additional attributes (I am thinking about event handlers) will probably have to be treated in the same way:
这是代码。您需要将标准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>
#10
5
I'm going to be brave and throw my hat into the ring on this one (ancient as it is), see how many downvotes I can collect.
我要勇敢地把我的帽子扔进这枚戒指上(虽然它很古老),看看我能收集多少次失败的选票。
Here is my attempt, which does seem to work everywhere I have tested it (Chrome20, IE8 and FF14):
下面是我的尝试,它似乎适用于我测试过的所有地方(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);
}());
I placed this code in the <head>
and called it from the end of the <body>
to ensure my page is rendered before it starts arguing with the malicious code, don't know if this is the best approach, YMMV.
我将此代码放在中,并在末尾调用它,以确保在页面开始与恶意代码争论之前得到呈现,不知道这是否是最好的方法,YMMV。
How does it work?
它是如何工作的呢?
...I hear you ask - well the honest answer is, I don't really know. It took a lot of fudging about to make it work everywhere I was testing, and the exact effect that it has varies slightly depending on where you run it.
…我听到你问,诚实的回答是,我真的不知道。在我所测试的所有地方,它都需要进行大量的模糊操作,而且它的确切效果取决于你在哪里运行它。
Here is the thinking behind it:
它背后的想法是:
- Set a function to run at the lowest possible interval. The basic concept behind any of the realistic solutions I have seen is to fill up the scheduler with more events than the frame buster-buster has.
- 将函数设置为在可能的最低间隔运行。我所见过的任何实际解决方案背后的基本概念都是用比frame buster-buster更多的事件填充调度器。
- Every time the function fires, try and change the location of the top frame. Fairly obvious requirement.
- 每当函数触发时,尝试更改顶部框架的位置。相当明显的要求。
- Also schedule a function to run immediately which will take a long time to complete (thereby blocking the frame buster-buster from interfering with the location change). I chose a synchronous XMLHttpRequest because it's the only mechanism I can think of that doesn't require (or at least ask for) user interaction and doesn't chew up the user's CPU time.
- 还可以安排一个函数立即运行,这将花费很长时间来完成(从而阻止frame buster-buster来干扰位置的改变)。我选择了同步XMLHttpRequest,因为我能想到的唯一一种机制不需要(或至少不需要)用户交互,也不会占用用户的CPU时间。
For my http://mysite.tld/page-that-takes-a-while-to-load
(the target of the XHR) I used a PHP script that looks like this:
为我的http://mysite。tld/page-that- at-take -a- to-load (XHR的目标)我使用的PHP脚本如下所示:
<?php sleep(5);
What happens?
会发生什么呢?
- Chrome and Firefox wait the 5 seconds while the XHR completes, then successfully redirect to the framed page's URL.
- Chrome和Firefox在XHR完成后等待5秒,然后成功重定向到框架页面的URL。
- IE redirects pretty much immediately
- IE立即重定向
Can't you avoid the wait time in Chrome and Firefox?
难道你不能避免Chrome和Firefox的等待时间吗?
Apparently not. At first I pointed the XHR to a URL that would return a 404 - this didn't work in Firefox. Then I tried the sleep(5);
approach that I eventually landed on for this answer, then I started playing around with the sleep length in various ways. I could find no real pattern to the behaviour, but I did find that if it is too short, specifically Firefox will not play ball (Chrome and IE seem to be fairly well behaved). I don't know what the definition of "too short" is in real terms, but 5 seconds seems to work every time.
显然不是。起初,我将XHR指向一个返回404的URL——这在Firefox中是行不通的。然后我试着睡觉;为了得到这个答案,我最终采用了这个方法,然后我开始用不同的方式来计算睡眠时间。我找不到这种行为的真正模式,但我的确发现,如果它太短,特别是火狐不会打球(Chrome和IE似乎表现得相当不错)。我不知道“太短”的定义是什么,但5秒似乎每次都有效。
If any passing Javascript ninjas want to explain a little better what's going on, why this is (probably) wrong, unreliable, the worst code they've ever seen etc I'll happily listen.
如果任何路过的Javascript忍者想要更好地解释发生了什么,为什么这(很可能)是错误的、不可靠的、他们见过的最糟糕的代码等等,我会很高兴地听着。
#11
5
As of 2015, you should use CSP2's frame-ancestors
directive for this. This is implemented via an HTTP response header.
从2015年开始,您应该使用CSP2的框架-祖先指令。这是通过HTTP响应头实现的。
e.g.
如。
Content-Security-Policy: frame-ancestors 'none'
Of course, not many browsers support CSP2 yet so it is wise to include the old X-Frame-Options
header:
当然,目前还没有多少浏览器支持CSP2,所以最好包含旧的X-Frame-Options头:
X-Frame-Options: DENY
I would advise to include both anyway, otherwise your site would continue to be vulnerable to Clickjacking attacks in old browsers, and of course you would get undesirable framing even without malicious intent. Most browsers do update automatically these days, however you still tend to get corporate users being stuck on old versions of Internet Explorer for legacy application compatibility reasons.
无论如何,我建议两者都包括,否则你的网站将继续容易受到旧浏览器的点击攻击,当然,即使没有恶意的意图,你也会得到不受欢迎的框架。现在大多数浏览器都是自动更新的,但是由于遗留的应用程序兼容性的原因,公司用户仍然会被困在旧版本的ie浏览器上。
#12
4
Well, you can modify the value of the counter, but that is obviously a brittle solution. You can load your content via AJAX after you have determined the site is not within a frame - also not a great solution, but it hopefully avoids firing the on beforeunload event (I am assuming).
你可以修改计数器的值,但这显然是一个脆弱的解决方案。在确定站点不在框架内之后,您可以通过AJAX加载内容——这也不是一个很好的解决方案,但它有望避免触发before卸载事件(我假设)。
Edit: Another idea. If you detect you are in a frame, ask the user to disable javascript, before clicking on a link that takes you to the desired URL (passing a querystring that lets your page know to tell the user that they can re-enable javascript once they are there).
编辑:另一个想法。如果您检测到您在一个框架中,请用户在单击将您带到所需URL的链接之前禁用javascript(传递一个查询字符串,该查询字符串允许您的页面知道用户可以在javascript存在时重新启用它)。
Edit 2: Go nuclear - if you detect you are in a frame, just delete your document body content and print some nasty message.
编辑2:去核-如果你发现你在一个框架,只要删除你的文件正文内容和打印一些下流的信息。
Edit 3: Can you enumerate the top document and set all functions to null (even anonymous ones)?
编辑3:能否枚举顶部文档并将所有函数设置为null(甚至是匿名函数)?
#13
4
If you add an alert right after the buster code, then the alert will stall the javascript thread, and it will let the page load. This is what * does, and it busts out of my iframes, even when I use the frame busting buster. It also worked with my simple test page. This has only been tested in Firefox 3.5 and IE7 on windows.
如果您在buster代码之后添加一个警告,那么这个警告将会使javascript线程停止,并且它会让页面载入。这就是*的功能,它会从我的iframe中跳出来,即使我使用了frame buster。它也适用于我的简单测试页面。这只在Firefox 3.5和IE7中测试过。
Code:
代码:
<script type="text/javascript">
if (top != self){
top.location.replace(self.location.href);
alert("for security reasons bla bla bla");
}
</script>
#14
3
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.
注意:我并没有测试这个。
#15
2
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);
}
})();
#16
2
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:
如果查看setInterval()返回的值,它们通常是单位数,所以通常可以使用一行代码禁用所有此类中断:
for (var j = 0 ; j < 256 ; ++j) clearInterval(j)
#17
2
I might just have just gotten a way to bust the frame buster buster javascript. Using the getElementsByName in my javascript function, i've set a loop between the frame buster and the actual frame buster buster script. check this post out. http://www.phcityonweb.com/frame-buster-buster-buster-2426
我可能刚刚找到了一种方法来破坏框架破坏者javascript。使用我的javascript函数中的getElementsByName,我在frame buster脚本和frame buster脚本之间设置了一个循环。看看这篇文章。http://www.phcityonweb.com/frame -巴斯特克星-巴斯特- 2426
#18
0
setInterval and setTimeout create an automatically incrementing interval. Each time setTimeout or setInterval is called, this number goes up by one, so that if you call setTimeout, you'll get the current, highest value.
setInterval和setTimeout创建一个自动递增的间隔。每次调用setTimeout或setInterval时,这个数字就会增加1,所以如果调用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";
}
Since it is almost unheard of for there to be 10000 simultaneous setIntervals and setTimeouts working, and since setTimeout returns "last interval or timeout created + 1", and since top.clearInterval is still accessible, this will defeat the black-hat attacks to frame websites which are described above.
因为几乎没有人听说过有10000个同步的setinterval和setTimeouts在工作,而setTimeout返回“最后一个interval或创建+ 1的timeout”,并且从top开始。clearInterval仍然是可访问的,这将击败黑帽攻击框架网站如上所述。
#19
0
Use htaccess to avoid high-jacking frameset, iframe and any content like images.
使用htaccess避免高帧集、iframe和任何内容(如图像)。
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.
这将显示一个版权页面,而不是预期。
#1
139
I'm not sure if this is viable or not - but if you can't break the frame, why not just display a warning. For example, If your page isn't the "top page" create a setInterval method that tries to break the frame. If after 3 or 4 tries your page still isn't the top page - create a div element that covers the whole page (modal box) with a message and a link like...
我不确定这是否可行,但如果你不能打破框架,为什么不显示一个警告。例如,如果您的页面不是“顶部页面”,那么创建一个试图破坏框架的setInterval方法。如果在3或4次尝试之后,你的页面仍然不是顶部页面——创建一个div元素,包含整个页面(模态框),其中包含一条消息和一个链接,比如……
You are viewing this page in a unauthorized frame window - (Blah blah... potential security issue)
你正在一个未经授权的框架窗口中查看这个页面。潜在的安全问题)
click this link to fix this problem
单击此链接可解决此问题。
Not the best, but I don't see any way they could script their way out of that.
不是最好的,但我看不出他们有什么办法来摆脱它。
#2
199
FWIW, most current browsers support the X-Frame-Options: deny directive, which works even when script is disabled.
FWIW是目前大多数浏览器都支持X-Frame-Options: deny指令,即使禁用了脚本,它也能工作。
IE8:
http://blogs.msdn.com/ie/archive/2009/01/27/ie8-security-part-vii-clickjacking-defenses.aspx
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
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
Chrome / Webkit http://blog.chromium.org/2010/01/security-in-depth-new-security-features.html http://trac.webkit.org/changeset/42333
#3
29
We have used the following approach in one of our websites from http://seclab.stanford.edu/websec/framebusting/framebust.pdf
我们在一个网站上使用了以下方法: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>
#4
29
Came up with this, and it seems to work at least in Firefox and the Opera browser.
这个想法出现了,至少在Firefox和Opera浏览器中是可行的。
if(top != self) {
top.onbeforeunload = function() {};
top.location.replace(self.location.href);
}
#5
19
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.
使用_top作为windows .open()的目标参数将在同一个窗口中启动它。
#6
19
Considering current HTML5 standard that introduced sandbox for iframe, all frame busting codes that provided in this page can be disabled when attacker uses sandbox because it restricts the iframe from following:
考虑到目前为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
Please see: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-iframe-element.html#attr-iframe-sandbox
请参见:http://www.whatwg.org/specs/web-apps/current-work/multipage/the-iframe-element.html # attr-iframe-sandbox
Now, consider attacker used the following code to host your site in iframe:
现在,考虑攻击者使用以下代码在iframe中托管您的站点:
<iframe src="URI" sandbox></iframe>
Then, all JavaScript frame busting code will fail.
然后,所有的JavaScript框架破坏代码都将失败。
After checking all frame busing code, only this defense works 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>
that originally proposed by Gustav Rydstedt, Elie Bursztein, Dan Boneh, and Collin Jackson (2010)
最初由Gustav Rydstedt, Elie Bursztein, Dan Boneh和Collin Jackson提出(2010)
#7
6
if (top != self) {
top.location.replace(location);
location.replace("about:blank"); // want me framed? no way!
}
#8
5
Ok, so we know that were in a frame. So we location.href to another special page with the path as a GET variable. We now explain to the user what is going on and provide a link with a target="_TOP" option. It's simple and would probably work (haven't tested it), but it requires some user interaction. Maybe you could point out the offending site to the user and make a hall of shame of click jackers to your site somewhere.. Just an idea, but it night work..
我们知道这是在一个坐标系中。所以我们的位置。href到另一个特殊页面,路径为GET变量。我们现在向用户解释发生了什么,并提供一个带有target="_TOP"选项的链接。它很简单,很可能会工作(还没有测试过),但是它需要一些用户交互。也许你可以向用户指出这个冒犯你的网站,并让那些点击你网站的人感到羞愧。只是一个想法,但它是夜间工作。
#9
5
All the proposed solutions directly force a change in the location of the top window. What if a user wants the frame to be there? For example the top frame in the image results of search engines.
所有提议的解决方案都直接强制改变顶部窗口的位置。如果用户希望帧在那里呢?例如,搜索引擎图像结果的顶部框架。
I wrote a prototype where by default all inputs (links, forms and input elements) are disabled and/or do nothing when activated.
我编写了一个原型,在默认情况下,所有输入(链接、表单和输入元素)都被禁用,或者在激活时什么都不做。
If a containing frame is detected, the inputs are left disabled and a warning message is shown at the top of the page. The warning message contains a link that will open a safe version of the page in a new window. This prevents the page from being used for clickjacking, while still allowing the user to view the contents in other situations.
如果检测到包含的帧,则将禁用输入,并在页面顶部显示一条警告消息。警告消息包含一个链接,该链接将在新窗口中打开页面的安全版本。这阻止了页面被用于点击,同时仍然允许用户在其他情况下查看内容。
If no containing frame is detected, the inputs are enabled.
如果没有检测到包含帧,则启用输入。
Here is the code. You need to set the standard HTML attributes to safe values and add additonal attributes that contain the actual values. It probably is incomplete and for full safety additional attributes (I am thinking about event handlers) will probably have to be treated in the same way:
这是代码。您需要将标准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>
#10
5
I'm going to be brave and throw my hat into the ring on this one (ancient as it is), see how many downvotes I can collect.
我要勇敢地把我的帽子扔进这枚戒指上(虽然它很古老),看看我能收集多少次失败的选票。
Here is my attempt, which does seem to work everywhere I have tested it (Chrome20, IE8 and FF14):
下面是我的尝试,它似乎适用于我测试过的所有地方(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);
}());
I placed this code in the <head>
and called it from the end of the <body>
to ensure my page is rendered before it starts arguing with the malicious code, don't know if this is the best approach, YMMV.
我将此代码放在中,并在末尾调用它,以确保在页面开始与恶意代码争论之前得到呈现,不知道这是否是最好的方法,YMMV。
How does it work?
它是如何工作的呢?
...I hear you ask - well the honest answer is, I don't really know. It took a lot of fudging about to make it work everywhere I was testing, and the exact effect that it has varies slightly depending on where you run it.
…我听到你问,诚实的回答是,我真的不知道。在我所测试的所有地方,它都需要进行大量的模糊操作,而且它的确切效果取决于你在哪里运行它。
Here is the thinking behind it:
它背后的想法是:
- Set a function to run at the lowest possible interval. The basic concept behind any of the realistic solutions I have seen is to fill up the scheduler with more events than the frame buster-buster has.
- 将函数设置为在可能的最低间隔运行。我所见过的任何实际解决方案背后的基本概念都是用比frame buster-buster更多的事件填充调度器。
- Every time the function fires, try and change the location of the top frame. Fairly obvious requirement.
- 每当函数触发时,尝试更改顶部框架的位置。相当明显的要求。
- Also schedule a function to run immediately which will take a long time to complete (thereby blocking the frame buster-buster from interfering with the location change). I chose a synchronous XMLHttpRequest because it's the only mechanism I can think of that doesn't require (or at least ask for) user interaction and doesn't chew up the user's CPU time.
- 还可以安排一个函数立即运行,这将花费很长时间来完成(从而阻止frame buster-buster来干扰位置的改变)。我选择了同步XMLHttpRequest,因为我能想到的唯一一种机制不需要(或至少不需要)用户交互,也不会占用用户的CPU时间。
For my http://mysite.tld/page-that-takes-a-while-to-load
(the target of the XHR) I used a PHP script that looks like this:
为我的http://mysite。tld/page-that- at-take -a- to-load (XHR的目标)我使用的PHP脚本如下所示:
<?php sleep(5);
What happens?
会发生什么呢?
- Chrome and Firefox wait the 5 seconds while the XHR completes, then successfully redirect to the framed page's URL.
- Chrome和Firefox在XHR完成后等待5秒,然后成功重定向到框架页面的URL。
- IE redirects pretty much immediately
- IE立即重定向
Can't you avoid the wait time in Chrome and Firefox?
难道你不能避免Chrome和Firefox的等待时间吗?
Apparently not. At first I pointed the XHR to a URL that would return a 404 - this didn't work in Firefox. Then I tried the sleep(5);
approach that I eventually landed on for this answer, then I started playing around with the sleep length in various ways. I could find no real pattern to the behaviour, but I did find that if it is too short, specifically Firefox will not play ball (Chrome and IE seem to be fairly well behaved). I don't know what the definition of "too short" is in real terms, but 5 seconds seems to work every time.
显然不是。起初,我将XHR指向一个返回404的URL——这在Firefox中是行不通的。然后我试着睡觉;为了得到这个答案,我最终采用了这个方法,然后我开始用不同的方式来计算睡眠时间。我找不到这种行为的真正模式,但我的确发现,如果它太短,特别是火狐不会打球(Chrome和IE似乎表现得相当不错)。我不知道“太短”的定义是什么,但5秒似乎每次都有效。
If any passing Javascript ninjas want to explain a little better what's going on, why this is (probably) wrong, unreliable, the worst code they've ever seen etc I'll happily listen.
如果任何路过的Javascript忍者想要更好地解释发生了什么,为什么这(很可能)是错误的、不可靠的、他们见过的最糟糕的代码等等,我会很高兴地听着。
#11
5
As of 2015, you should use CSP2's frame-ancestors
directive for this. This is implemented via an HTTP response header.
从2015年开始,您应该使用CSP2的框架-祖先指令。这是通过HTTP响应头实现的。
e.g.
如。
Content-Security-Policy: frame-ancestors 'none'
Of course, not many browsers support CSP2 yet so it is wise to include the old X-Frame-Options
header:
当然,目前还没有多少浏览器支持CSP2,所以最好包含旧的X-Frame-Options头:
X-Frame-Options: DENY
I would advise to include both anyway, otherwise your site would continue to be vulnerable to Clickjacking attacks in old browsers, and of course you would get undesirable framing even without malicious intent. Most browsers do update automatically these days, however you still tend to get corporate users being stuck on old versions of Internet Explorer for legacy application compatibility reasons.
无论如何,我建议两者都包括,否则你的网站将继续容易受到旧浏览器的点击攻击,当然,即使没有恶意的意图,你也会得到不受欢迎的框架。现在大多数浏览器都是自动更新的,但是由于遗留的应用程序兼容性的原因,公司用户仍然会被困在旧版本的ie浏览器上。
#12
4
Well, you can modify the value of the counter, but that is obviously a brittle solution. You can load your content via AJAX after you have determined the site is not within a frame - also not a great solution, but it hopefully avoids firing the on beforeunload event (I am assuming).
你可以修改计数器的值,但这显然是一个脆弱的解决方案。在确定站点不在框架内之后,您可以通过AJAX加载内容——这也不是一个很好的解决方案,但它有望避免触发before卸载事件(我假设)。
Edit: Another idea. If you detect you are in a frame, ask the user to disable javascript, before clicking on a link that takes you to the desired URL (passing a querystring that lets your page know to tell the user that they can re-enable javascript once they are there).
编辑:另一个想法。如果您检测到您在一个框架中,请用户在单击将您带到所需URL的链接之前禁用javascript(传递一个查询字符串,该查询字符串允许您的页面知道用户可以在javascript存在时重新启用它)。
Edit 2: Go nuclear - if you detect you are in a frame, just delete your document body content and print some nasty message.
编辑2:去核-如果你发现你在一个框架,只要删除你的文件正文内容和打印一些下流的信息。
Edit 3: Can you enumerate the top document and set all functions to null (even anonymous ones)?
编辑3:能否枚举顶部文档并将所有函数设置为null(甚至是匿名函数)?
#13
4
If you add an alert right after the buster code, then the alert will stall the javascript thread, and it will let the page load. This is what * does, and it busts out of my iframes, even when I use the frame busting buster. It also worked with my simple test page. This has only been tested in Firefox 3.5 and IE7 on windows.
如果您在buster代码之后添加一个警告,那么这个警告将会使javascript线程停止,并且它会让页面载入。这就是*的功能,它会从我的iframe中跳出来,即使我使用了frame buster。它也适用于我的简单测试页面。这只在Firefox 3.5和IE7中测试过。
Code:
代码:
<script type="text/javascript">
if (top != self){
top.location.replace(self.location.href);
alert("for security reasons bla bla bla");
}
</script>
#14
3
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.
注意:我并没有测试这个。
#15
2
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);
}
})();
#16
2
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:
如果查看setInterval()返回的值,它们通常是单位数,所以通常可以使用一行代码禁用所有此类中断:
for (var j = 0 ; j < 256 ; ++j) clearInterval(j)
#17
2
I might just have just gotten a way to bust the frame buster buster javascript. Using the getElementsByName in my javascript function, i've set a loop between the frame buster and the actual frame buster buster script. check this post out. http://www.phcityonweb.com/frame-buster-buster-buster-2426
我可能刚刚找到了一种方法来破坏框架破坏者javascript。使用我的javascript函数中的getElementsByName,我在frame buster脚本和frame buster脚本之间设置了一个循环。看看这篇文章。http://www.phcityonweb.com/frame -巴斯特克星-巴斯特- 2426
#18
0
setInterval and setTimeout create an automatically incrementing interval. Each time setTimeout or setInterval is called, this number goes up by one, so that if you call setTimeout, you'll get the current, highest value.
setInterval和setTimeout创建一个自动递增的间隔。每次调用setTimeout或setInterval时,这个数字就会增加1,所以如果调用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";
}
Since it is almost unheard of for there to be 10000 simultaneous setIntervals and setTimeouts working, and since setTimeout returns "last interval or timeout created + 1", and since top.clearInterval is still accessible, this will defeat the black-hat attacks to frame websites which are described above.
因为几乎没有人听说过有10000个同步的setinterval和setTimeouts在工作,而setTimeout返回“最后一个interval或创建+ 1的timeout”,并且从top开始。clearInterval仍然是可访问的,这将击败黑帽攻击框架网站如上所述。
#19
0
Use htaccess to avoid high-jacking frameset, iframe and any content like images.
使用htaccess避免高帧集、iframe和任何内容(如图像)。
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.
这将显示一个版权页面,而不是预期。