什么是CSRF攻击?
CSRF就是跨站请求伪造攻击,怎么理解呢?
首先我们来理解cookie机制,就是当你登录某个网站,从后端接收的cookie会存到浏览器中,你下次访问该网站时浏览器会将属该网站的cookies带过去。
那么如果黑客编写了一个页面,将你登录过的网站接口链接放入该页面,那你点击访问黑客写的页面就会访问你登录过的那个网站,这时候浏览器会认为是你在访问该网站就将cookie带过去,则黑客访问成功。
下面有一个例子,有一个接口是Get方法
在启动另一个项目的页面,该页面如下,
只需一个img标签,里面链接为黑客想访问的链接,当你点击这个页面就会自动访问这个接口。
然后我们登录第一个项目的系统之后,然后点击编写好那个伪造请求页面。可以看到访问成功,这就是CSRF攻击,不需要获取你的cookie也可以伪造你的请求去访问。
这只是get方法类型,同样post类型也可以实现,只需要创建iframe标签通过表单提交,(document表单submit没有受到同源策略影响,所以可以提交)
下面是test1.html的内容
如何防范CSRF攻击
我们来讲其中的一种方式,令牌验证。通俗地来讲,就后端给前端发一个令牌,每次调用接口时需要把令牌带上,后端进行验证,否则就调用失败。就是利用黑客的页面不能直接获取cookie的值,进行防御的一个机制。
以下是详细过程:
在登录接口设计发送令牌过程,令牌的值是一个随机值然后进行MD5散列得到一个字符串,通过保存到cookie发回给前端,需要设置httponly为false,不然前端的js获取不了该值。
String authorization = HashStrUtil.hash(String.valueOf(authorizationNum), "MD5");
session.setAttribute("authorization",authorization);
Cookie cookie = new Cookie("authorization", authorization);
cookie.setPath("/");
cookie.setHttpOnly(false);
servletResponse.addCookie(cookie);
但是这样就不能防止XSS攻击获取cookie,然后再通过CSRF攻击,所以我们应该尽可能地把cookie的过期时间设置短一点,但也不是百分百安全,但攻破的条件已经很苛刻了。
前端处置方式:
发送ajax请求调用后端接口时,需要带上cookie中的令牌。存在http请求的head部
$.ajax({
type: "GET",
dataType: "json",
url: "user/getFriends",
headers:{
"authorization":getCookie("authorization")
},
success:
})
后端进行验证:
在Spring项目中我们创建一个拦截器,在调用接口时拦截,判断该请求是否带有令牌且与存在session的是否一致。
//判断该http请求 head首部是否带有authorization和是否与服务器存的一致,一致则通过
String authorization = request.getHeader("authorization");
String authorizationSession = (String) session.getAttribute("authorization");
if (authorization != null && authorizationSession != null && authorization.equals(authorizationSession)) {
return true;
}else {
return false;
}
下面实验下效果:已经无法访问。
如果是http请求,黑客是可以通过抓包进行获取你的发送的请求,所以以上防范是基于https进行的。