为啥自引用 iframe 不会无限循环并导致我的机器崩溃?

Posted

技术标签:

【中文标题】为啥自引用 iframe 不会无限循环并导致我的机器崩溃?【英文标题】:Why does a self-referencing iframe not infinitely loop and crash my machine?为什么自引用 iframe 不会无限循环并导致我的机器崩溃? 【发布时间】:2012-12-22 19:35:11 【问题描述】:

我用iframe 创建了一个简单的html 页面,它的src 属性引用了包含页面——换句话说,一个自引用的iframe。

this.html

<html>
<head></head>
<body>
<iframe src="this.html"></iframe>
</body>
</html>

为什么这不会无限循环并导致我的浏览器崩溃?另外,为什么连 IE 都不会崩溃?

(注意:这源于团队讨论使用 iframe 解决问题的优点和缺点。你知道,“镜子的镜子”之类的。)

【问题讨论】:

值得深思,这实际上在某个时候(1999 年?)得到了解决,但我想知道其基本原理是什么? bugzilla.mozilla.org/show_bug.cgi?id=8065 这里已经讨论过了:***.com/questions/5763508/iframe-to-infinity 简而言之,浏览器对 iframe 嵌套设置了限制。 您的代码毕竟能够破坏一件事。我的开发工具:dl.dropbox.com/u/8989748/devtools_broken.png。我希望你现在快乐:( 1000 分 “为什么连 IE 都不崩溃?” 【参考方案1】:

W3C 在 1997 年解决了这个问题,解释了应该如何在“Implementing HTML Frames”中实现框架:

任何试图将其任何祖先使用的 URL 分配为其 SRC 的框架都被视为根本没有 SRC URL(基本上是一个空白框架)。


iframe 递归错误/攻击历史

正如 kingdago 发现并在上面的评论中提到的那样,1999 中的一个浏览器是 Mozilla 没有为此实施保护措施。引用其中一位开发人员的话:

这是一个自 MSIE5 以来的奇偶校验错误(也是可能造成尴尬的根源) 这类页面没有问题。

我决定对此进行深入研究,结果发现这发生在 2004again。但是,这次涉及到 JavaScript

这是代码,是什么原因造成的: 直接跟在后面 一个包含这个的脚本: frames.productcatalog.location.replace(frames.productcatalog.location + location.hash);

...

实际结果:父窗口被递归加载到 iframe,有时会导致崩溃。

预期结果:就像在 Internet Explorer 中一样显示。

然后again 在 2008 中使用 Firefox 2(这也涉及 javascript)。

还有again 2009。这里有趣的部分是这个错误仍然打开并且这个附件:https://bugzilla.mozilla.org/attachment.cgi?id=414035(你会抑制你的好奇心吗?)仍然会崩溃/冻结你的Firefox(我刚刚测试过它,我几乎崩溃了整个 Ubuntu)。在 Chrome 中,它只是无限期地加载(可能是因为每个选项卡都位于一个单独的进程中)。


至于其他浏览器:

2005 年 Konqueror 的安全措施中有一个错误,允许渲染 iframe one inside another(但似乎不知何故它并没有冻结/崩溃整个应用程序)。 IE6、Opera 7.54 和 Firefox 0.9.3 也 reported 容易受到基于 iframe 递归的攻击。

【讨论】:

你是一个了不起的人@Konrad 谢谢@kingdango。这是一个很好的问题,我最终对“iframe 递归错误/攻击”历史进行了研究,查看我的更新答案。 @Konrad 正如我在下面的回答中所说明的那样,今天所有版本的 IE 仍然可以进行 iframe 递归攻击 - 也就是说,如果可以利用我发现的通用崩溃。 你也可以在现代浏览器中创建这种行为——它只需要 JavaScript:例如frame.src = 'http://0.0.0.0:9922/index.html?' + new Date().getTime()【参考方案2】:

我想在问题的“另外,为什么连 IE 都不崩溃?” 部分添加一些内容。 IE 没有让我们失望...

如果您将简单的迭代次数作为查询字符串添加到嵌套 iFrame 的 src Firefox 中,其他人将在某个迭代深度后停止。 IE - 我们使用 IE 版本 10 对此进行了测试 - 只是崩溃了 :)

this.php

<html>
<head></head>
<body>
<iframe src="this.php?q=<?php echo (isset($_GET['q'])?$_GET['q']:1)+1?>" />
</body>
</html>

【讨论】:

我爱你内心那个让你测试这个的人。【参考方案3】:

IE 6.0 可以在没有脚本的情况下崩溃:

<iframe src="this.html?c=9"></iframe>

我不确定为什么这不会触发循环检测,也不确定它是否已更改。

【讨论】:

以上是关于为啥自引用 iframe 不会无限循环并导致我的机器崩溃?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在循环开始时调用 requestAnimationFrame 不会导致无限递归?

为啥这个 Scanf 会导致无限循环?

为啥for循环在c中无限进行

React 组件中的错误导致应用程序重新渲染,从而导致无限循环。为啥?

为啥这会导致无限循环

为啥分叉我的进程会导致文件被无限读取