什么是CSRF攻击?

CSRF就是跨站请求伪造攻击,怎么理解呢?

首先我们来理解cookie机制,就是当你登录某个网站,从后端接收的cookie会存到浏览器中,你下次访问该网站时浏览器会将属该网站的cookies带过去。

那么如果黑客编写了一个页面,将你登录过的网站接口链接放入该页面,那你点击访问黑客写的页面就会访问你登录过的那个网站,这时候浏览器会认为是你在访问该网站就将cookie带过去,则黑客访问成功。

下面有一个例子,有一个接口是Get方法

Spring Boot结合FFmpeg_ajax

在启动另一个项目的页面,该页面如下,

Spring Boot结合FFmpeg_CSRF_02

只需一个img标签,里面链接为黑客想访问的链接,当你点击这个页面就会自动访问这个接口。

然后我们登录第一个项目的系统之后,然后点击编写好那个伪造请求页面。可以看到访问成功,这就是CSRF攻击,不需要获取你的cookie也可以伪造你的请求去访问。

Spring Boot结合FFmpeg_首部_03

这只是get方法类型,同样post类型也可以实现,只需要创建iframe标签通过表单提交,(document表单submit没有受到同源策略影响,所以可以提交)

Spring Boot结合FFmpeg_Spring Boot结合FFmpeg_04

下面是test1.html的内容

Spring Boot结合FFmpeg_ajax_05

 

如何防范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;
            }

下面实验下效果:已经无法访问。

Spring Boot结合FFmpeg_笔记_06

如果是http请求,黑客是可以通过抓包进行获取你的发送的请求,所以以上防范是基于https进行的。