保护 iFrame - 只允许它在一个域上工作

Posted

技术标签:

【中文标题】保护 iFrame - 只允许它在一个域上工作【英文标题】:Protecting iFrame - Only allow it to work on one domain 【发布时间】:2011-12-31 11:01:16 【问题描述】:

我创建了一个小部件,并使用 iFrame 将其嵌入到其他网站上。我要做的是确保没有人可以查看源代码并复制 iFrame 代码并将其放在自己的网站上。

我可以在数据库中存储它应该被允许的 URL。我以前见过它,一个站点有一个很长的加密代码,如果它与域不匹配,那么它会说 Access Denied..

有人知道我该怎么做吗?

谢谢!

【问题讨论】:

绝对不可能的许多色调。 +1 @Rook。与 Mech Software 进行了一次对话,让我好好思考一下,但是,当然,你是绝对正确的。 :-) 【参考方案1】:

不,你不能这样做。您可以做的最好的事情是:

if (window.top.location.host != "hostname") 
    document.body.innerhtml = "Access Denied";

将以上内容添加到您的 javascript 中,然后使用 JavaSript obfuscator

【讨论】:

我将您的 DOM 引用更正为 window.top.location.host - 这将引用顶部框架的主机(尝试嵌入小部件的站点),而不是 window.location.host,它将是提供小部件。 当我将它添加到我的代码并查看它在 Firebug 中嵌入的站点时,我得到这个:“访问属性‘主机’的权限被拒绝” @Drew 只需检查 window.top.location,然后 @Cheekysoft 这在跨域站点中不起作用。它授予 Permission denied 以访问 firebug 中的属性主机 在跨域情况下,window.top 的任何属性都将为空,因此您也无法检查位置。【参考方案2】:

您无法阻止人们查看您的 HTML,但有些标题可以让您指定哪些网站可以嵌入您的 iframe。查看X-Frame-Options 标头和Content-Security-Policyframe-ancestors 指令。尊重它的浏览器在嵌入到其他人的网站时会拒绝加载 iframe。

【讨论】:

【参考方案3】:

在服务器上,在 IFRAME 中显示的页面的代码中,检查 Referer 标头的值。除非出于隐私原因阻止此标头,否则它包含托管 IFRAME 的页面的 URL。

【讨论】:

referrer 很容易被欺骗。永远不要依赖它(或任何其他 HTTP 标头) 当然可以,但某些任意客户端浏览器不会被欺骗。他并不是要阻止人们查看他的来源,他只是想阻止人们将框架放在他们自己的网站上。【参考方案4】:

你所要求的几乎是不可能的。如果您在网络上提供源代码,则有人可以以一种或另一种方式复制它。任何 javascript 技巧都可以通过使用 wget 或 curl 等低级工具来解决。

因此,即使您保护它,您仍然会发现理论上有人可以复制代码(因为浏览器会接收它),并且如果确定的话,可以将它放在他们自己的网站上。

【讨论】:

不可能阻止某人查看小部件是如何嵌入的,但不是不可能阻止您的小部件正常运行,如果它可以确定它已被 iframe它不想去的地方。 @Cheekysoft 我同意你可以让它无法操作,但这种解决方案不会对确定的人起作用。这行代码可以很容易地通过使用 file_get_contents 的 php 文件运行,并用静态值替换该行,从而完全击败它。 一个很好的观点;你是绝对正确的。如果小部件依赖与母机的通信来运行,那么这可以得到补救。将一些关键功能放在您的服务器上并使用 XHR 调用它,这将必须确认同源策略,因此如果有人更改并重新发布 JS 代码,则会失败。 @Cheekysoft 没错。但是,这可以通过不将其嵌入 iframe 来解决。让 js 代码本身在页面上创建 iframe,这样来源始终是正确的。当然,这仍然可以被欺骗,但在那个时候更难使用。 @Cheekysoft 我认为这在很大程度上取决于小部件。如果它是一个简单的小部件,您会认为不需要任何安全性。【参考方案5】:

我遇到了同样的问题,但我在主页上返回了用户。我传播了这个决定。

必须放在有 iframe 的地方

<script>
        $(window).load(function () 
            var timetoEnd = '';   
            var dstHost   = 'YOUR-ALLOW-HOST';
            var backToUrl = 'BACK-TO-URL';

            function checkHost()
                var win = window.frames.YOUR-IFRAME-NAME;
                win.postMessage('checkHost', dstHost);
                    console.log('msg Sended');
                    clearInterval(timetoEnd);
                    timetoEnd = setInterval(function () 
                        window.location.href = backToUrl;
                    , 5000);
                

                function validHost(event) 
                    if (event.data == 'checkHostTrue') 
                        clearInterval(timetoEnd);
                        console.log('checkHostTrue');
                     else 
                        return;
                    
                

                window.addEventListener("message", validHost, false);
                checkHost();

                setInterval(function () 
                    checkHost();
                , 10000
                );
            );
    </script>

它必须放在你的 src iframe 中

<script>
            function receiveMessage(event)
            
                if(event.data=='checkHost')
                    event.source.postMessage("checkHostTrue",
                           event.origin);
                 else 
                    return;
                
            
            window.addEventListener("message", receiveMessage, false);
</script>

【讨论】:

【参考方案6】:

我知道这是个老话题,但我有代码,你刚刚在 &lt;script&gt; 标签中添加了代码,它应该可以防止大多数好奇的人从 iFrame 中查看 html 文件:

if(window.top.location.pathname === window.location.pathname)
history.back()

【讨论】:

这将在点击 history.back 之前引发异常......并且从框架历史记录的第一页返回将带您到您已经在的页面。 This answer 是今天的明智之选。

以上是关于保护 iFrame - 只允许它在一个域上工作的主要内容,如果未能解决你的问题,请参考以下文章

仅在特定域上加载 iframe

无法访问 iframe 中加载的自己域上的 httponly 标记 cookie

保护 iframe 免受其他人的侵害并为 iframe 使用一个域?

以前工作的 iframe 中出现“Chrome 检测到异常代码”错误

将事件发送到不同域上的 iFrame?

iframe jQuery 不会在 Internet Explorer 中执行 [所有版本]