如何防止我的网站页面被第三方网站的iFrame框架加载

89

在页面加载期间,我如何确定我的页面被嵌入到其他网站的框架中? 我猜referrer请求标头不能帮助我这里?谢谢。


嗨,约翰,我不能说我需要完整的解决方案,只是移动方向就足够了。当我找到问题的答案后,我总是将其发布为答案,这是我参与社区的唯一方式。 - Andriy Kopachevskyy
注意:设置元标记是无效的!例如,<meta http-equiv="X-Frame-Options" content="deny"> 没有任何效果。不要使用它!只有通过 HTTP 标头进行设置,如下面的示例,X-Frame-Options 才能起作用。https://developer.mozilla.org/fr/docs/Web/HTTP/Headers/X-Frame-Options - xpredo
9个回答

106

在服务器端无法检测它,但你可以在页面加载后使用JavaScript来检测它。比较topself,如果它们不相同,则表示当前页面被嵌套在了一个框架中。

此外,一些现代浏览器支持 X-FRAME-OPTIONS 头信息,该头信息有两个值:

  • DENY – 如果页面被嵌套在一个框架中,则防止页面被呈现
  • SAMEORIGIN – 与上述相同,除非页面属于与顶层框架集持有者相同的域。

Google的Picasa等用户不能被嵌入到框架中。

支持该头信息的浏览器及其最低版本:

  • IE8和IE9
  • Opera 10.50
  • Safari 4
  • Chrome 4.1.249.1042
  • Firefox 3.6.9(老版本需要使用NoScript插件)

2
自从我通过谷歌搜索进入这里,我想补充一下:Firefox在2010年8月加入了X-FRAME-OPTIONS,并在FF3.6.9中实现了它: http://michael-coates.blogspot.com/2010/08/x-frame-option-support-in-firefox.html - ThePants
从OWASP https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet#Defending_with_X-Frame-Options_Response_Headers - ASKN
1
这个答案已经过时了。请参考CSP - samb102

46

Stackoverflow 包含一些 JS 代码用于测试(master.js)。这是相关部分:

if(top!=self){
    top.location.replace(document.location);
    alert("For security reasons, framing is not allowed; click OK to remove the frames.")
}

但要记住JS可能会被禁用。


如果您想将一条信息传达给嵌入您内容的iframe的人,或是查看iframe中您内容的最终用户,那么采用这种方法会非常有帮助。 - kevinmicke

33

对于现代浏览器,您可以使用CSP(内容安全策略),这是一种标准。以下标头将防止文档在任何框架中加载:

Content-Security-Policy: frame-ancestors 'none'

(不过,IE 11需要使用X-前缀)。您还可以将'none'更改为允许框架的来源,例如您自己的网站。

为了覆盖旧版浏览器,最好与@Maerlyn的答案一起使用。


1
恕我直言,您的回答不够清晰。这是标题代码还是PHP?例如。 - Gary Carlyle Cook
2
@GaryCarlyleCook 这是一个 HTTP 头,应该作为响应浏览器提供页面的一部分。它不是 PHP 代码,但你可以使用 PHP 发送它;请参见 header() - rvighne

15

您可以使用JavaScript防止页面加载到iframe中

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

这段代码会将您页面中的iframe所在容器的地址更改为您页面的地址,并强制容器显示您的页面。


2
iframe上的sandbox属性允许禁止这种框架逃避黑客攻击。因此,如果您关心安全问题,则这种方法不是一种安全的防止框架的方式。 - Frédéric

7

如果您不介意某些地方有您的内容,但不希望它出现在特定网站上,您可以阻止特定域名。例如,如果 offendingdomain.com 嵌入了您的内容,则可以执行以下操作:

<script type="text/javascript">
    if(document.referrer.indexOf("offendingdomain.com") != -1) {
        window.location = "http://www.youtube.com/watch_popup?v=oHg5SJYRHA0";
    }
</script>

这段代码会检查父文档的位置,并查看是否是嵌入您的内容的offendingdomain.com。这个脚本会将该iframe发送到一个著名的Youtube视频作为惩罚。实际上,他们只是自己被Rick-Rolled了。


3
使用JavaScript检查是否在iframe上加载,将以下脚本放置在您的PHP文件末尾,并重定向到显示警告或提示的页面,说明您的页面不应使用iframe加载。
<script type="text/javascript">
if(top.location != window.location) {
    window.location = '/error_iframe.php';
}
</script>

1
<?php
    header("Content-Security-Policy: frame-ancestors 'none'");
?> 

0

我在头部使用这段PHP代码

if($_SERVER['SERVER_NAME'] != 'yourwebsite.com'){
   header('location: yourwebsite.com');
}

如果有人嵌入了你的网站,它会重定向到你的网站。


0

将 hosname 替换为域名

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接