Hot For Coding

关于HTTP Response响应头字段X-Frame-Options

X-Frame-Options

什么是X-Frame-Options

HTTP有一个特殊的Response响应头字段X-Frame-Options,它可以指示是否允许浏览器在<iframe><frame><embed><object>里渲染。许多站点可以利用这个头字段避免clickjacking的攻击,这是一个浏览器安全问题,简单来说就是可以使用程序模拟用户恶意点击页面相关的DOM元素,比如在登录页面点击登录按钮等等,造成页面短时间内登录动作频繁造成服务器有压力从而达到攻击目的。所以才会有[CSRF: Cross-site request forgery](https://en.wikipedia.org/wiki/Cross-site_request_forgery)出现,当然这不是今天讨论的话题,感兴趣的朋友可以去看看。

X-Frame-Options有两个值

X-Frame-Options: DENY
X-Frame-Options: SAMEORIGIN

  • DENY,就是禁止显示在<iframe><frame><embed><object>标签
  • SAMEORIGIN,相比上一条就是同源的情况下可以显示

默认不响应这个字段的话就是没有任何限制

iframe嵌入第三方服务

有时候,你需要iframe嵌入一些第三方服务在你的页面里,正好第三方服务做了这个限制,比如Grafana,Gitlab等为了安全,默认情况下会Respoonse Headers带X-Frame-Options: DENY,如以下摘自Gitlab某个页面的Response,它带了X-Frame-Options: DENY信息。

Response
:status: 200
Content-Type: text/html; charset=utf-8
Vary: Accept-Encoding
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Content-Encoding: gzip
Referrer-Policy: strict-origin-when-cross-origin, strict-origin-when-cross-origin
Cache-Control: max-age=0, private, must-revalidate, no-store
Date: Wed, 27 May 2020 09:42:22 GMT
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
ETag: W/"d0183a9b27acd2a2571c038069950af1"
x-runtime: 0.159561
Server: nginx
x-download-options: noopen
x-permitted-cross-domain-policies: none
x-request-id: Jbod8TtfHl2
Strict-Transport-Security: max-age=31536000
x-ua-compatible: IE=edge

这种情况下,你要是使用iframe嵌入Gitlab页面,浏览器会在读到Response里存在X-Frame-Options: DENY信息后停止渲染,并在console打出一条错误信息

Refused to display 'http://gitlab.example.com' in a frame because it set 'X-Frame-Options' to 'deny'.

解决这个方法只能看一下第三方服务有没有提供相关的配置文件,比如Grafana的配置文件里就有一个allow_embedding = true | false字段用于配置是否在Response里带X-Frame-Options: DENY信息。

使用反向代理

有的时候,第三方服务没有提供相关的配置,也没有源码,这个时候可以增加一层反向代理解决X-Frame-Options相关问题,下面以Nginx为例子

如果你希望强行加上X-Frame-Options限制别人iframe嵌入,可以这么干

nginx.conf

...
location /third-service/ {
   add_header 'X-Frame-Options' 'DENY';
   proxy_pass ​http://third-service.com​;
}
...

如果你不想被X-Frame-Options受限制,但第三方服务强行带了这个X-Frame-Options字段,你也可以在Response的时候把这个头字段给去掉

nginx.conf

...
location /third-service/ {
   proxy_hide_header X-Frame-Options;
   proxy_pass ​http://third-service.com​;
}
...

以上配置在Nginx Response回客户端之前把上游响应的头字段X-Frame-Options移除掉,这样就接触限制了

当然,一山有一山高,你可以在前面加一个Nginx反向代理添加X-Frame-Options头字段,别人也可以在架一层Nginx把你的X-Frame-Options给移除掉。

分享

TITLE: 关于HTTP Response响应头字段X-Frame-Options

LINK: https://www.qttc.net/526-http-header-x-frame-options.html

NOTE: 原创内容,转载请注明出自琼台博客