【问题标题】:Javascript, track iframes redirecting top windowJavascript,跟踪 iframe 重定向顶部窗口
【发布时间】:2018-05-15 14:06:40
【问题描述】:

由于除了沙盒之外没有其他方法可以阻止 iframe 重定向顶部框架,这会阻止可见度跟踪所需的其他功能,因此我想跟踪重定向。由于一个站点可以有多个 iframe,因此它可以是其中任何一个。

有什么方法可以跟踪/找出是哪一个(特定 iframe)导致了顶部框架重定向?

这是一个沙箱(使用浏览器控制台并启用保留日志):

注意 iframe 内容通常是跨域的。为了便于使用,它在 Sandox 中。

【问题讨论】:

标签: javascript iframe


【解决方案1】:

我们可以使用 iframe.contentWindow.document 之类的东西访问 iframe 内容,但如果我们观察到 Same-origin policy,这是可能的。

另一种方法是设置Content-Security-Policy 标头,例如:

<meta http-equiv="Content-Security-Policy" content="frame-src http://example.com">

父页面中的此标题可防止在框架中加载与http://example.com 不同的站点,还有一种方法可以report 拒绝发送帖子的行为,但不幸的是不能使用&lt;meta&gt; 标签设置(它是仅服务器端)。使用这种方法,我们必须执行白名单,所以我认为在这种情况下它可能没有用。但是,如果第一次给出白名单,可能会设置所有站点可用,所以当 iframe 重定向时,浏览器会拒绝加载它。

如果不是同源的情况和执行白名单的可能性,那么我认为我们可以做的更好的是调用 iframe onunload 事件,不幸的是,当 iframe 页面重新加载时也会触发此事件不仅在重定向上。我认为这是最接近的方法。为此,此代码有效。

var srcs = ["iframe2.html","iframe.html","iframe2.html"];


        for (let i = 0; i < srcs.length; i++) {
            var iframe = document.createElement('iframe'); 
                iframe.src = srcs[i]; 
                iframe.name = "i"+i; 
                document.body.appendChild(iframe);
                window["i"+i].onunload = function(){console.log("change "+i)}
        }

当然onunload 是第一次触发,当所有 iframe 加载时,重定向是第 2 次第 3 次等等。但我们可以排除第一种情况。

这里是一个完整的例子https://codesandbox.io/s/o16yk7mqy,我创建了iframe3.html,它既不会刷新也不会重新加载以清楚地表明这一点。我还创建了一个简单的重定向或重新加载 iframe 列表。

更新 据我所知,您想要的是设置具有sandbox 属性的 iframe,并将您想要的所有内容列入白名单,但没有allow-top-navigation,例如:

<iframe src="iframe.html" sandbox="allow-script allow-forms allow-popups allow-pointer-lock allow-same-origin"></iframe>

正如我在 cmets 中所说,至少在 Chrome 64.0.3282.167 中,当 iframe 尝试重定向顶部框架时,当我们委托除了 allow-top-navigation 之外的所有内容时,它会抛出异常。 Firefox 中的行为不同(至少 58.0.2)。 Firefox 拒绝顶部导航,但继续执行代码。

因此,作为结论,我认为最好的方法是 sanbox 和 onunload 或仅 onunload 的组合。当然,如果可能的话,Content-Security-Policy 是最安全、更灵活的方式。这取决于实施。我认为不涉及服务器端代码来执行完美的解决方案几乎是不可能的。有白名单要检查,比如这个 API https://developers.google.com/safe-browsing/v4/ 有黑名单要检查,看看这个帖子 https://security.stackexchange.com/questions/32058/looking-for-url-blacklists-of-malicious-websites

【讨论】:

  • 这对识别带有错误代码/重定向的 iframe 有何帮助?
  • @user2693017 i是srcs的key,即iframe重定向或重载
  • 如果 i = 0 它是 iframe2.html ,如果 i = 1 它是 iframe.html 等等
  • 不幸的是,这在这种情况下没有帮助。 1.内容是问题中提到的跨站点。 2. sn-p 仅在页面重新加载/加载时触发,但在其中一个 iframe 调用顶部重定向时不会触发。在这种情况下,什么都没有触发 :( 请参阅:transfer.sh/%28/InnNq/example.zip%29.tar.gz(codesandbox 似乎已经改变了一些东西,不允许在沙箱中发生重定向)
  • 在最后一条评论之后,至少 chrome 64.0.3282.167 将限制作为异常执行,因此它不会在异常之后执行任何代码。如果 iframe 尝试做一些受限制的事情,它会抛出异常。至少 firefox 58.0.2 没有,所以我们可以使用 ononload 或任何东西。也许这就是问题所在。
【解决方案2】:

如果您可以控制所有框架,则可以使用postMessage 实现框架之间的交互。流程:

  1. 框架想要执行重定向 - 它通过重定向请求向父框架发送消息。
  2. 父框架执行重定向并知道哪个框架导致了重定向。

家长:

window.addEventListener("message", (event) => {
    // show message source (your frame)
    console.log(event.source);

    const message = event.data;
    console.log(`Frame ID: ${message.frameId}`);

    if(message.messageType === "redirect") {
        window.location.href = message.redirectUrl;
    }
});

子框架:

function redirect(url) {
    var message = {
        messageType: "redirect",
        frameId: "frame1"
        redirectUrl: url
    }
    window.parent.postMessage(message, "*");
}

【讨论】:

  • 不幸的是我们没有。它们也是跨域的。
【解决方案3】:

您可以在重定向到另一个域/应用程序之前显示一个对话框,然后用户可以决定 - 留下还是离开当前应用程序。您还可以跟踪当前目标(即您的情况下的 iframe)。

window.onbeforeunload = function (e) {
  console.log(e.currentTarget.location.href);
  return 'Stop redirection. Show dialog box.';
};

【讨论】:

    【解决方案4】:

    从各个 iframe 中,您可以在重定向发生时设置 cookie 吗?假设它是从 iframe1 发生的,你可以设置一个类似

    的 cookie
    document.trackFrame = "FrameName=iframe1";  
    

    一旦重定向完成,您是否可以尝试读取 cookie 并确定是哪个 iframe 导致了重定向?

    【讨论】:

    • 我们不控制 iframe 的内容
    猜你喜欢
    • 2023-04-02
    • 2011-02-23
    • 1970-01-01
    • 1970-01-01
    • 2023-02-17
    • 1970-01-01
    • 1970-01-01
    • 2014-11-15
    • 2011-10-21
    相关资源
    最近更新 更多