Apache X-Frame-Options 允许来自多个域的 Allow-From

10

当我在使用Apache的x-frame headers选项时,出现了错误。

Header always append X-Frame-Options ALLOW-FROM site1,site2,site3

或者

Header always append X-Frame-Options ALLOW-FROM=site1,site2,site3

或者

Header always append X-Frame-Options ALLOW-FROM=site1
Header always append X-Frame-Options ALLOW-FROM=site2
Header always append X-Frame-Options ALLOW-FROM=site3

我该如何设置X-Frame-Options: ALLOW-FROM来支持多个域名?

谢谢!

7个回答

11

值得注意的是,ALLOW-FROM指令已从Firefox 70中移除,其他浏览器也可能会跟随。您需要改用CSP的frame-ancestors指令,在约95%的浏览器中受支持。

那么您的示例代码将如下所示:

Header always append Content-Security-Policy "frame-ancestors site1 site2 site3;"

编辑:在新浏览器中,frame-ancestors会覆盖X-FRAME-OPTIONS,因此理论上您可以在那里为旧浏览器设置值,并使CSP在新浏览器中覆盖它,但问题是没有X-FRAME-OPTIONS的值可以让您嵌入到多个网页中。唯一有效的选项是deny(任何地方都不允许)、sameorigin(仅限您的网站)和allow-from(从现代浏览器中删除,仅允许一个站点)。

要覆盖的旧X-FRAME-OPTIONS值是根本没有。这将允许您将站点嵌入到其他多个站点中(所有站点),并在现代浏览器中限制它只能被允许的站点嵌入。

如果不允许在禁止站点中嵌入比在允许站点中嵌入更重要,则结合以上内容:

Header always append X-Frame-Options "DENY"

这将防止您的网站在大约3%的浏览器中被嵌入到所有网站中,在95%的浏览器中仅显示在允许的网站中,并在其余2%的浏览器中显示在所有位置(即使X-FRAME-OPTIONS也不支持所有地方)。


当真实的答案对于那些被大型企业特别需要的10%人群至关重要时,循环执行。 - raf
@ref 目前还没有一种 X-FRAME-OPTIONS 值可以让您在多个站点中嵌入 - 我已经更新了我的答案并提供了更多信息。 - Sora2455

6

编辑于2018年1月17日:以下是正确的内容:

Header set X-Frame-Options SAMEORIGIN
Header append X-Frame-Options "ALLOW-FROM http://www.example.com/"  
Header append X-Frame-Options "ALLOW-FROM http://example.com/"
Header append X-Frame-Options "ALLOW-FROM https://www.example.com/"
Header append X-Frame-Options "ALLOW-FROM https://example.com/"

基本上,您只允许来自您网站的iframe(SAMEORIGIN),并使用“append”指定允许的URL列表。如果您不添加“append”,每行都将覆盖前面的行。
这在Internet Explorer 11中实际上可以工作,在Firefox 57中无法工作,并且被Chrome忽略...
使用https://securityheaders.io进行测试将无法获得“A”,因为它们无法处理多个URI。
We couldn't detect a valid configuration. Expected values are "DENY", "SAMEORIGIN", "ALLOW-FROM (URL)" and "ALLOWALL".

另一种似乎在IE11和Firefox中有效的可能性是:
 Header always set X-Frame-Options "ALLOW-FROM https://www.example.fr/ https://example.fr/ http://www.example.fr/ http://example.fr/"

当你使用https://securityheaders.io检查结果时,它会给出“A”级。

顺便问一句,使用世界上最常用的浏览器(Chrome)可以绕过安全设置的点是什么?


谢谢!你的帖子让我发现我一直在使用set而不是append - christopher.theagen
当加载'http://<ipa>:8080/wordpress/'时,我遇到了无效的'X-Frame-Options'头:'ALLOW-FROM http://<ipa>:8080/wordpress/'不是一个被认可的指令。该头将被忽略。 - Siddharth
1
你在Apache中启用了mod_headers吗?你能提供更多关于你的配置的细节吗? - cetipabo
这些在Internet Explorer 11中不起作用。一个返回您的第一个配置示例标头的站点页面可以被任何站点成功地框架。一个返回您的第二个配置示例标头的站点页面只允许由https://www.example.fr(即出现在您的标头中的第一个站点)进行框架。仅使用https://securityheaders.io进行测试是不够的。您实际上需要通过来自不想允许框架的域的页面来测试您的页面。 - Simon Lieschke

4
SetEnvIf Referer "^(https:\/\/.*\.example1\.com)/.*" X_FRAME_OPTIONS_ALLOWED=$1
SetEnvIf Referer "^(https:\/\/.*\.example2\.com)/.*" X_FRAME_OPTIONS_ALLOWED=$1

Header set X-Frame-Options SAMEORIGIN
Header append X-Frame-Options "ALLOW-FROM %{X_FRAME_OPTIONS_ALLOWED}e" env=X_FRAME_OPTIONS_ALLOWED`

1
使用这些设置,客户端只会收到一个X-Frame选项。 X-Frame选项将是“SAMEORIGIN”或“ALLOW-FROM https://blog.example1.com”。这适用于Chrome和Firefox。 注意:我必须写always set而不是setappend才能使其工作。 - jgrocha

3

由于支持ALLOW-FROM的实现和浏览器支持情况不同,我尝试了以下解决方案,它可以设置SAMEORIGIN或有条件地完全删除X-Frame-Options

在apache-2.4上进行了测试。

# Set X-Frame-Options SAMEORIGIN _unless_ the referer is any of my allowed sites.
# Add one or more SetEnvIf - whatever suits your purpose
# This part you MUST adapt.

# ALLOW https://my.allowed.site.com
SetEnvIf Referer "^https:\/\/my\.allowed\.site\.com\/.*" X_FRAME_OPTIONS_ALLOWED

# ALLOW https://mysite.tld.com and https://yoursite.tld.com
SetEnvIf Referer "^https:\/\/(mysite|yoursite)\.tld\.com\/.*" X_FRAME_OPTIONS_ALLOWED

# ALLOW https://mysite.tld.com and https://yoursite.theother.org
SetEnvIf Referer "^https:\/\/(mysite\.tld\.com|yoursite\.theother\.org)\/.*" X_FRAME_OPTIONS_ALLOWED

# Set X-Frame-Options = SAMEORIGIN _unless_ the referer is in the allow list.
Header always set X-Frame-Options SAMEORIGIN env=!X_FRAME_OPTIONS_ALLOWED

# Always _unset_ X-Frame-Options if the referer is in the allow list.
Header always unset X-Frame-Options env=X_FRAME_OPTIONS_ALLOWED

您可以添加多个SetEnvIf,或扩展正则表达式-因人而异。
让事情更易读,您的同事会感谢您...

2
Header always append X-Frame-Options ALLOW-FROM=site1
Header always append X-Frame-Options ALLOW-FROM=site2
Header always append X-Frame-Options ALLOW-FROM=site3

这种方法是可行的。
但是我第一次使用它时出现了错误。
可能是我输入了错误的字符。


在PHP中如何做到这一点?是否可以将其包装在for循环内部以拥有多个标题?该怎么做? - Daniel Soublett

1
X-Frame-Options规范仅指定使用DENY、SAMEORIGIN和ALLOW-FROM之一(https://www.rfc-editor.org/rfc/rfc7034#section-2.1)。一些浏览器可能支持多个ALLOW-FROM,但许多浏览器根本不支持ALLOW-FROM。
您最好的选择是使用frame-ancestors指令实现Content-Security-Policy头。这允许配置多个URI,并且被大多数浏览器理解,但不包括IE和Edge 14及以下版本。
对于IE和Edge 14支持,您还可以使用ALLOW-FROM设置X-Frame-Options。如果创建一个值的白名单,您可以基于引用者设置ALLOW-FROM URI。

同时设置这两个头部信息不会有害。理解Content-Security-Policy frame-ancestors的浏览器将忽略X-Frame-Options,而不理解frame-ancestors的浏览器将忽略它并在可用时使用X-Frame-Options。结合https://caniuse.com/#search=csphttps://caniuse.com/#search=x-frame-options,这对除了"UC Browser for Android"之外的所有浏览器都有效。


1

编辑于2018年1月17日:

下面的解决方案是不正确的,因为每行的设置都会覆盖前面的设置,所以只允许使用http://example.com/

最终,我找到了正确的语法。根据这个网站: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options

Header set X-Frame-Options "ALLOW-FROM https://example.com/"

这对我有效:

Header always set X-Frame-Options "ALLOW-FROM https://www.example.com/"
Header always set X-Frame-Options "ALLOW-FROM https://example.com/"
Header always set X-Frame-Options "ALLOW-FROM http://www.example.com/"
Header always set X-Frame-Options "ALLOW-FROM http://example.com/"

1
你为什么没有在意识到这个答案不起作用时直接删除它呢? - CupawnTae

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