会话cookie中缺少HttpOnly属性会导致攻击者可以通过程序(JS脚本、Applet等)获取到用户的cookie信息,造成用户cookie信息泄露,增加攻击者的跨站脚本攻击威胁。
HttpOnly是微软对cookie做的扩展,该值指定cookie是否可通过客户端脚本访问。Microsoft Internet Explorer 版本 6 Service Pack 1 和更高版本支持cookie属性HttpOnly。如果在Cookie中没有设置HttpOnly属性为true,可能导致Cookie被窃取。窃取的Cookie可以包含标识站点用户的敏感信息,攻击者可以重播窃取的Cookie,以便伪装成用户或获取敏感信息,进行跨站脚本攻击等。如果在Cookie中设置HttpOnly属性为true,兼容浏览器接收到HttpOnly cookie,那么客户端通过程序(JS脚本、Applet等)将无法读取到Cookie信息,这将有助于缓解跨站点脚本威胁。
百度推荐解决办法:
正常百度这个漏洞,普遍的解决办法是让你添加过滤器,在过滤器中设置cookie(参见博客:https://blog.csdn.net/OliverQY/article/details/80846960)。但是小编在一个特殊的实际应用场景中发现,这种做法会存在一个隐藏问题,这种方式的确会在cookie中加上httponly的标识,但是会引发另一个问题。
特殊场景:
在单点登录的情况下,还是登录逻辑是调用第三方提供的登录接口来实现登录的情况下,就会出现一种现象:
第一步:正常登录进去,然后重启服务器
第二步:刷新界面,就会让你重新登录,但是你死活都停留在了登录的界面
原因:
-
第一步只是为了使客户端服务器保存一个会话cookieA
-
第二步并不是没有登录成功,而是第一次发登录请求req1的时候,cookie是第一步中的cooikeA。
-
服务端根据这个cookieA去session会话池中找不到这个sessionA,就重新打开了一个新的会话sessionB,将登录成功的信息都写在会话sessionB中
-
登录成功,前端js根据请求req1返回的结果,成功跳转到首页,发起了第二个请求req2,这个请求req2依旧使用的还是本地缓存的cookieA
-
于是服务端根据这个cookieA去session会话池中找不到这个sessionA,就又重新打开了一个新的会话sessionC,发现sessionC中没有任何信息,是个空的session,单点的过滤器就会把他转到登录界面,于是就又来到了登录界面。
小编推荐解决方案:
理论上,按照推荐的方法添加写cookie的过滤器应该把新会话的sessionID写到cookie中替换掉本地缓存的cookie才对,的确,如果替换掉了,也的确不会发生这个现象,但是他偏偏没有替换掉。抓包的过程中发现,请求的sessionID和返回的sessionID已经不一样了,但是他依然没有替换掉客户端缓存的cookie信息。
于是小编就在想,能不能从容器入手,去tomcat的官网一看,so easy,分分钟解决这个httponly的漏洞。参考链接:http://tomcat.apache.org/tomcat-6.0-doc/config/context.html 搜索关键字“httponly”。只需要在tomcat/conf/content.xml中的content节点加一个属性useHttpOnly=true即可。
<Context useHttpOnly="true">
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
</Context>
当然小编这里使用的是tomcat容器,目前有很多容器,但是小编相信主流的容器都会有等同于这个设置属性的,没事多看看官方文档。
在tomcat7以下的版本中这个属性默认是false,需要手动的设置为true,7及7以上版本中这个属性已经默认为false了。