CSRF学习总结
CSRF攻击:
Cross-Site Request Forgery。中文解释为:跨站请求伪造,具体流程如下图
也就是说CSRF攻击具备两个默认条件:
1.黑客没有暴力获取用户存储在浏览器中的cookie,同源策略仍然能有效保护
2.黑客无法获取用户直接访问A网站获取的响应,也就是说黑客也不能从响应中解析出任何有关用户的认证信息
得出的结论是黑客能做的就是做一个恶意网站,当用户访问这个恶意网站的时候,点击了某个链接,这个链接会向A网站发出请求。其余的暴力**session,劫持用户cookie信息的均不属于CSRF攻击
清楚了流程,那么要做好CSRF保护,可以从两个方面来实现:
第一:用户方面,用户每次访问网站之后及时退出,基本就能杜绝CSRF的攻击
第二:网站建立CSRF的保护机制,也就是俗称的CSRF保护
CSRF保护的手段:
一:验证HTTP Referer
http协议规定,在浏览器发出请求的时候,会在请求头headers里附加Referer字段,该字段负责记录此次请求的来源地址。比如当用户通过www.baidu.com点击某链接a访问网站A的时候,浏览器发出请求,request headers里面就会附带这么一条信息:Referer:链接a的页面的url
网站A通过对Referer信息的校验,只要请求来源不是自己站内发出的的请求,统统拒绝,这样也能防范CSRF攻击
缺点:过度依赖HTTP协议,如果某浏览器没有严格遵循,或者因为用户害怕浏览记录被泄漏而关掉Referer,那么当用户正常请求网站A的时候,会因为Referer验证不通过而被视为CSRF攻击,从而请求被拒绝。严重影响用户体验
二:使用令牌(token)
分析CSRF攻击的原理可以知道,CSRF之所以能成功,恰恰是因为黑客利用了浏览器的特性:在访问网站的时候,会携带上该网站的所有cookie。那么,将用户的有关的权限信息不存储在cookie里面,并且,由于同源策略的保护(非同协议,同IP,同端口的不能使用同一个脚本)。其实就不会收到CSRF的攻击了。
补充:同源策略例子:
在没有被用户授权的情况下
当用户打开网站A页面的时候如果需要执行脚本文件(例如javascript),会识别此脚本文件是不是来自于网站A,如果是就执行,不是就不执行。
比较安全的做法在于,当用户要获取网站A的用户权限的时候,网站A通过了校验,生成一个token令牌,令牌中包含随机信息,随着响应一起发送给用户。同时网站可以将token存储在本地的sessin中。当用户再向网站A发出post/put/delete请求的时候,js文件控制在请求中附加上token的信息,网站A收到请求后,首先验证是否携带token,以及携带的token值是否正确,如果正确则接收此次请求并处理,如果不正确,拒绝请求。
写的过程中突然好像又明白了一个问题,之前一直在想,如果token被劫持了之后,岂不是只要在token有效期内也能任意被使用,后来想了一下,http协议是分层的,传输层需要考虑的问题,为什么要在应用层烦恼。
记录两个网址:
https://www.v2ex.com/t/276207
https://security.stackexchange.com/questions/81756/session-authentication-vs-token-authentication(外文)
里面的讨论很好的区别了基于token的实现和基于session的实现
jwt就是基于token的一种实现,有空研究一下jwt