原帖位于IT老兵博客,沉淀着一个IT老兵对于这个行业的认知。
Java:“目标服务器没有返回一个X-Frame-Options头”的解决方案。
在涉及网站安全时遇到一个问题(360网站安全测试也会报告),“目标服务器没有返回一个X-Frame-Options头”,找了网上的帖子,说的都不是太清楚,所以研究总结一下,方便后人。
以下摘录一下对于安全网站这个问题的描述和建议解决方案:
概要
目标服务器没有返回一个X-Frame-Options头。
攻击者可以使用一个透明的、不可见的iframe,覆盖在目标网页上,然后诱使用户在该网页上进行操作,此时用户将在不知情的情况下点击透明的iframe页面。通过调整iframe页面的位置,可以诱使用户恰好点击iframe页面的一些功能性按钮上,导致被劫持。
解决方案
修改web服务器配置,添加X-frame-options响应头。赋值有如下三种:
(1)DENY:不能被嵌入到任何iframe或frame中。
(2)SAMEORIGIN:页面只能被本站页面嵌入到iframe或者frame中。
(3)ALLOW-FROM uri:只能被嵌入到指定域名的框架中。
也可在代码中加入,在PHP中加入:
header(‘X-Frame-Options: deny’);
但是我们的环境是Java
的Springmvc
,这个应该怎么解决呢?其实Spring
框架中的security
本身有对这个问题的解决方案,但是这是之前的Spring
框架中的(SSH
那会的),现在用了SpringMVC
了,应该怎么去解决这个问题呢?
参考这里,这里介绍说配置项目的web.xml文件如下,即可解决问题:
<filter>
<filter-name>httpHeaderSecurity</filter-name>
<filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
<init-param>
<param-name>antiClickJackingOption</param-name>
<param-value>SAMEORIGIN</param-value>
</init-param>
<async-supported>true</async-supported>
</filter>
<filter-mapping>
<filter-name>httpHeaderSecurity</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
但是我这里又引出一个新的问题:
cvc-complex-type.2.4.a: Invalid content was found starting with element ‘async-supported’. One of ‘{“http://java.sun.com/xml/ns/javaee“:run-as, “http://java.sun.com/xml/ns/javaee“:security-role-ref}’ is expected.
意思是说async-supported
这个元素不被识别。继续探索,找到这里说的:
xmlns中再加两行:
http://www.springmodules.org/schema/cache/springmodules-cache.xsd
http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd
要在web.xml顶部的xmlns
里面再加两行,问题才真正得到了解决。
问题是解决了,但是问题产生的原因和解决的方法又是什么呢?
找到Tomcat
官网的讲解:
org.apache.catalina.filters.HttpHeaderSecurityFilter .//过滤器的类名
……
antiClickJackingOption //参数配置,可以设置成DENY(拒绝),SAMEORIGIN(同源),ALLOW-FROM(允许从哪里来的)
What value should be used for the anticlick-jacking header? Must be one of DENY, SAMEORIGIN, ALLOW-FROM (case-insensitive). If not specified, the default value of DENY will be used.
意思是说HttpHeaderSecurityFilter
这个过滤器是用来做anticlick-jacking
(防止点击劫持,Java
做Web
服务的优越性就在这里,很多功能都已经做成了工具类,只需要配置一下即可)。三个配置选项,我们上文中配置成了SAMEORIGIN(同源),安全性就大大提高了。
那么,上面配置这个过滤器就搞明白了,那么后面出现的那个问题又是怎么回事呢?
这里要研究一下这段语句的意思,在web.xml的头部,可能很多人总会看到它,但不会去思考它:
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee
http://www.springmodules.org/schema/cache/springmodules-cache.xsd
http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
xmlns
:xml
的namespace
,这个是为了解决多个开发者对于xml的命名会产生冲突的问题。
xmlns:xsi
:定义了xml
的标准前缀。
xsi:schemaLocation
:xml
的schema
定义的位置。
简言之,Java
对于xml
的名值设置了一套定义规则,发布在上面的地方,我们上面使用的这个元素名async-supported
,在之前的web.xml
中所定义的位置是没有找到的,加了那两行的命名空间的定义,才可以找到这个元素定义的位置。
至此,问题基本搞明白了。