需求
接到上级命令,需要对网站做安全加固。
- 增加响应头,cache-control:no-store
- 增加HSTS,Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
- 增加secure,所有cookie都需要设置成secure的
第一次
需要改造的共有两个项目,业务模块和单点认证服务器模块(采用cas实现)
首先想到的是在http服务器层面进行配置,简单可控,在httpd上启用mod_header模块,增加以下配置:
<IfModule headers_module>
Header edit Set-Cookie ^(.*)$ $1;Secure
Header set Strict-Transport-Security "max-age=15768000"
Header add Cache-Control "no-store"
</IfModule>
第二次
运维同志告知,cookie的属性只能在应用内自己添加
看了一下项目,业务服务改下web.xml
认证服务是cas,基于springboot的。改下配置就可以了。
改完发现,业务端使用了dwr,而web.xml中的配置并不能影响到其他的cookies的设置,相当于没有改全,所以需要增加filter处理,干脆全加filter,不改动任何配置。
第三次
先说业务端代码。增加个filter,加三个开关对应三个需求点,这样如果投产有问题,只要关闭开关就和什么都没有发生一样。
-
项目使用了spring-security,即使不在filter中处理,ss也会增加cache-control的响应头。但是对于静态文件是不加的。
-
filter中如果开关开启,那么add一个响应头,cache-control:no-store ,过滤掉图片url,其他相应都加。
-
HSTS,注意: Strict-Transport-Security 在通过 HTTP 访问时会被浏览器忽略
-
开关开启,那么set一个响应头,没别的了。
-
spring-securiry也会增加这个响应头,但是条件是请求是https的
-
secure,拿到的request的cookies,并不能获取path属性
-
如果是http请求中,设置cookies的secure属性,对chrome并无任何效果,既不会增加cookies也不会修改。
-
判断如果请求是https的,那么重新add一个cookie,domain不设置,path就写死contextPath
CAS端代码类似,但是CAS本身已经提供了cache-control和hsts的配置,只需要在配置文件中打开即可。所以这两个配置其实是重复的。
第四次
本以为万事大吉。但是请运维同事查看生产cas的响应头的,发现cas并没有设置hsts,代码里有为啥没设置呢? 唯一的判断是request不是https的。
后来确实是这种情况,生产环境ssl证书在F5上就卸载了,后续apache和jboss并没有证书了,请求都是http的,所以没有加上。
- 修改filter,去掉所有request.isSecure()的判断,不管什么环境,都加上这些响应头。
- http环境,修改cookie的secure属性无效,这里说的修改其实就是add一个相同name的cookie。浏览器不处理,可能是因为他认为不安全吧。
第五次
发现cas的session对应的cookie写成了两份。一个cas自己写的path是/cas/
一个是filter中增加,path是/cas(contentpath)。 那么cas的path是怎么配置的path呢?
-
原来是spring-session,重新定义了一套request和session,然后用redis存储session数据,跟踪源码。发现设置的cookie,name叫SESSION,path就是 request.getContextPath()+ "/" 。 好了,这样可以放心大胆的在filter中写死path了,为了灵活和应对其他状况,这里还做了一个数据库配置,优先数据库配置。然后才是 request.getContextPath()+ "/"
-
cas还有一个cookie就是存的他的票证信息,这块就比较透明了,cookie的name,domain,path都在配置文件中。这里只需要获取配置中的信息进行设置即可了。同样做了一个数据库配置,优先级最高。
-
如果获取不到配置,就不做处理。
第六次
测试发现,每个请求都重新设置cookie太重复了。所以在session中增加一个标志位,每个cookie一个标志,如果已经设置过了,那么不设置。
还有一点,优化了日志,之前每个经过filter处理的读取配置参数,都要打印sql日志。如果系统超时,会不断有请求发来,那么后台日志会一直滚动。这里去掉多余的日志,并且配置的获取走缓存。
总结
其实中间还有一次,就是试图替换web.xml,改maven插件等这种,后来发现要改动各种流水线,并且光改web.xml也不能解决问题,就放弃了。
-
http接口响应设置hsts,响应头可以看见,但是浏览器并无任何效果不会主动跳转。因为 Strict-Transport-Security 在通过 HTTP 访问时会被浏览器忽略; 因为攻击者可以通过中间人攻击的方式在连接中修改、注入或删除它
-
https接口响应设置hsts,响应头可以看见,但是浏览器并无任何效果不会主动跳转。因为证书都是自制的,自签名的不好使。
-
http接口响应设置secure的cookie,无效。
-
http接口响应修改cookie的secure属性。无论修改成secure或者非,都无任何效果,不会修改,也不会新增。
-
老版本的浏览器,chrome45,http设置secure有效。
-
postman,http设置secure有效。
-
httpclient,http设置secure有效。
-
针对以上有效,最好还是真正的https环境打开secure的开关。不要在http环境设置secure,否则老浏览器,postman和代码都无法同步session了。
网友评论