CSRF攻击的原理和spring security的解决方法
CSRF概念
CSRF概念:CSRF跨站点请求伪造(Cross—Site Request Forgery),跟XSS攻击一样,存在巨大的危害性。可以这样来理解:
攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作,比如以你的名义发送邮件、发消息,盗取你的账号,添加系统管理员,甚至于购买商品、虚拟货币转账等。
CSRF攻击流程
以下图为例,一个用户通过浏览器成功登录一个网站,登陆成功后,服务器会返回一个该用户的唯一标识放入浏览器Cookie中,以此作为用户之后操作的唯一凭证。
假设此时该用户在此网站中请求一个表单类的网页,这时候用户又打开了另外的一个网站,而这个网站是一个病毒网站,它直接窃取了Cookie信息,当然也包括唯一身份凭证(因为cookie存在客户端中,所以很容易被窃取),通过唯一身份凭证,病毒网站直接进行用户所做的表单提交,而服务器是通过这个凭证来匹配用户信息的,服务器这时候无法识别病毒网站所做的操作,误以为是用户操作,此时可能造成用户严重损失。
Spring Security 对CSRF的解决方法
处理表单的CSRF攻击
Spring Security作为Spring提供的一个安全框架,使用它时,其内部便已经对CSRF攻击做了相关的防止工作(除了异步请求,因为异步请求没有前端表单)。
下面说一下Security对CSRF攻击所作的相关工作:
继续上图,然后解释:
首先在pom.xml引入:
<!--security-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
当你在项目中导入了SpringSecurity后,整个项目就直接被Security管理。之后我们再次登录相关网站后,在网站上请求一个会返回表单类的网页,这时候服务器不仅仅会存入一个带唯一标识的Cookie信息,还会在表单里带上一个类型为hidden的隐藏输入框,里面封装的就是security提供的另外一个随机唯一身份标识token,如图:
这个token值是随机生成的,每次访问表单页面时都会随机生成。病毒网站虽然可以窃取到cookie中的用户唯一标识,却无法获取给该用户的随机token,这就能防止csrf攻击所造成的影响。病毒网站发的请求中没有token,就会被security判定为伪造的请求,从而拒绝访问。
处理异步请求的CSRF攻击
但是有一些情况,security是无法做处理的,比如异步请求,因为异步请求是没有前端表单页面的,这时候我们需要在代码中做一些处理配置,才能达到在异步请求中防止CSRF的要求。
下面演示security在异步请求的情况下对防止csrf攻击的一些处理:
首先需要在触发异步请求的前端界面上(index.html)设置以下数据:
<!--访问该页面时,在此处生成CSRF令牌.-->
<meta name="_csrf" th:content="${_csrf.token}">
<meta name="_csrf_header" th:content="${_csrf.headerName}">
当刷新当前界面时,会得到token随机标识,
在发送异步请求的js中,将这些数据携带到请求头中。(每个异步请求的请求头都需要这样处理)
// 发送AJAX请求之前,将CSRF令牌设置到请求的消息头中.
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
$(document).ajaxSend(function(e, xhr, options){
xhr.setRequestHeader(header, token);
});
之后在提交ajax请求的时候会带着随机生成的token发送给服务器:
最后security会根据token判断这个请求是否是伪造的,从而决定是否拒绝访问。