如何防止IFRAME重定向顶级窗口


133

一些网站具有用于“破解” IFRAME附件的代码,这意味着,如果将页面A作为IFRAME父页面加载到内部,则P某些Javascript A会将外部窗口重定向到A

通常,此Javascript如下所示:

<script type="text/javascript">
  if (top.location.href != self.location.href)
     top.location.href = self.location.href;
</script>

我的问题是:作为父页面P的作者而不是内部页面的作者A如何防止A这种突破?

PS在我看来,这应该是跨站点安全性违规,但事实并非如此。


如果您不是框架内容的作者,我认为您根本无能为力。
scunliffe

Answers:


43

尝试使用onbeforeunload属性,该属性将使用户选择是否要离开页面。

示例:https//developer.mozilla.org/en-US/docs/Web/API/Window.onbeforeunload

在HTML5中,您可以使用沙盒属性。请参阅下面的Pankrat答案。 http://www.html5rocks.com/zh-CN/tutorials/security/sandboxed-iframes/


1
iFrame 确实允许使用进行跨域通信postMessage。这不是安全风险,但是当有人看到您的评论时,可能会担心知道此功能存在。:)
coreyward

在撰写此答案时是不可能的。感谢您指出。
fasih.rana'2

@SirDarius您能举个例子,非常感谢。
user198989 2015年

用户将不知道为什么会出现此确认,并且可能会选择一个随机响应。我不建议使用它。还有其他解决方案- sandbox
oriadam

1
@ fasih.rana第二篇文章对我有很大帮助。谢谢;)
MrD

127

使用HTML5,添加了iframe沙箱属性。在撰写本文时,此功能可在Chrome,Safari,Firefox和IE和Opera的最新版本上使用,但几乎可以满足您的要求:

<iframe src="url" sandbox="allow-forms allow-scripts"></iframe>

如果要允许顶级重定向,请指定sandbox="allow-top-navigation"


等等...什么 他们让你这样做吗?我以为如果一个网站想要爆发,所有浏览器都会允许它。人们应该如何在这种情况下使他们的网站脱离iframe?我没有抱怨,太棒了。
Farzher 2012年


1
@StephenSarcsamKamenar如果要保护您的网站不被显示在iframe中,则可以使用带有SAMEORIGIN值的X-Frame-Options标头。大多数现代浏览器都不会在带有此标头的iframe中显示网站。
Grzegorz

4
不幸的是sandbox,不允许在沙盒框架中使用Flash或任何其他类型的对象,从而使该sandbox功能在许多情况下无用。
oriadam

1
网站不应“爆发”以抗议被纳入iframe。他们可以简单地显示一条消息或空白。不幸的是,允许脚本在iframe中运行仍然会使您陷入流氓iframe的运行while(1){}和其他无限循环的境地。我希望每个iframe都能拥有自己的线程。
Gregory Magarshak '17

51

我使用沙盒=“ ...”

  • allow-forms允许表单提交
  • allow-popups允许弹出窗口
  • allow-pointer-lock允许指针锁定
  • allow-same-origin允许文档保持其原点
  • allow-scripts允许JavaScript执行,还允许功能自动触发
  • allow-top-navigation允许通过浏览顶层窗口使文档脱离框架

顶部导航是您要防止的,因此将其省略,将不会被允许。任何遗漏的东西都会被阻止

例如

        <iframe sandbox="allow-same-origin allow-scripts allow-popups allow-forms" src="http://www.example.com"</iframe>

3
请注意,Flash(和任何其他对象)也将被阻止,没有选择允许它。此“安全功能”阻止我一起使用沙箱
oriadam 2015年


4

我知道问题已经解决很久了,但是这是我的改进版本,只有在加载iframe时,它将等待500ms进行后续调用。

<script type="text/javasript">
var prevent_bust = false ;
    var from_loading_204 = false;
    var frame_loading = false;
    var prevent_bust_timer = 0;
    var  primer = true;
    window.onbeforeunload = function(event) {
        prevent_bust = !from_loading_204 && frame_loading;
        if(from_loading_204)from_loading_204 = false;
        if(prevent_bust){
            prevent_bust_timer=500;
        }
    }
    function frameLoad(){
        if(!primer){
            from_loading_204 = true;
            window.top.location = '/?204';
            prevent_bust = false;
            frame_loading = true;
            prevent_bust_timer=1000;
        }else{
            primer = false;
        }
    }
    setInterval(function() {  
        if (prevent_bust_timer>0) {  
            if(prevent_bust){
                from_loading_204 = true;
                window.top.location = '/?204';
                prevent_bust = false;
            }else if(prevent_bust_timer == 1){
                frame_loading = false;
                prevent_bust = false;
                from_loading_204 = false;
                prevent_bust_timer == 0;
            }



        }
        prevent_bust_timer--;
        if(prevent_bust_timer==-100) {
            prevent_bust_timer = 0;
        }
    }, 1);
</script>

onload="frameLoad()"onreadystatechange="frameLoad();"必须被添加到该帧或iframe。



2

由于您在iframe中加载的页面可以使用setInterval执行“突破”代码,因此onbeforeunload可能不那么实际,因为它可能会向用户显示“您确定要离开吗?” 对话。

还有一个iframe安全属性,该属性仅适用于IE和Opera

:(


2

在我的情况下,我希望用户访问内部页面,以便服务器将其IP视为访问者。如果我使用php代理技术,我认为内页会将我的服务器IP视为访问者,因此效果不佳。到目前为止,我唯一的解决方案是onbeforeunload。把它放在你的页面上:

<script type="text/javascript">
    window.onbeforeunload = function () {                       
         return "This will end your session";
    }
</script>

这既在Firefox中工作,也就是我测试过的东西。您会发现使用evt.return(what)废话之类的版本...在Firefox中不起作用。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.