一、Springboot安全之防CSRF攻击

(一)简要介绍
  跨站请求伪造(Cross-site request fogery),也被称为one-click attack或者session riding,通常缩写为CSRF或者XSRF,是一种挟制用户在当前已登录的WEB应用程序上执行非本意的操作的攻击方法。

  举个栗子:

  • 用户小z登录了网站A,同时打开网站B
  • 网站B隐蔽的发送一个请求至网站A
  • 网站A通过session、cookie等身份标记判断是用户小z,执行对应操作

  这样网站B内的非法代码就盗用了用户小z的身份,在小z不知情的情况下执行了攻击者需要的操作,这就是跨站请求伪造。

(二)术语解释:

CSRF Token
  服务端为客户端生成令牌,这个令牌将用于请求合法性校验,一般通过请求头或请求参数传递到服务端。

CSRF Token仓库
  服务端组件,用于从请求加载或生成CSRF Token。Spring Security提供了Cookie和HttpSession两种实现。

CSRF请求校验匹配器
  服务端组件,用于判断请求是否需要CSRF校验。

(三)防止攻击逻辑

  • 利用CSRF Token仓库将Http请求获取CSRF Token(该过程可以理解为Web服务端针对当前请求获取CSRF Token)。
  • 通过CSRF Token校验请求匹配器来判断当前请求是否需要CSRF Token校验,若需要,执行下一步;否则,跳过校验。
  • 先从请求头中获取CSRF Token值,若不存在,再从请求参数中获取。(该过程可以理解为获取Web客户端请求中的CSRF Token):
      若均未获取到,将会转向错误页面,并且相应头状态码为:403;
      若CSRF Token值获取到,执行下一步。
  • 将第1步CSRF Token仓库获取的CSRF Token与客户端请求中的CSRF Token进行比较:
       若两值相同,校验通过;
       若不相同,校验失败,将会转向错误页面,并且相应状态码为:403。

(四)CSRF Token仓库
  接口:org.springframework.security.web.csrf.CsrfTokenRepository

Cookie类型(默认)
  实现类:org.springframework.security.web.csrf.CookieCsrfTokenRepository
  CSRF Token存储:客户端,Web浏览器Cookie
  有效时间:Web浏览器会话期间
  特别注意:Cookie方式安全系数相对较低

HttpSession类型
  实现类:org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository
  CSRF Token存储:服务端,HttpSession(Servlet容器)
  有效时间:HttpSession 最大不活动时间间隔(#setMaxInactiveInterval(int) )
  特别注意:Servlet 容器需要支持HttpSession复制(分布式HttpSession)

(五)案例演示
添加依赖:

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>

1、创建login.html页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
</head>
<body>
<form id="form" method="post">
    <label>用户名:</label><input name="username" type="text" value="" />
    <label>密码:</label><input name="password" type="text" value="" />
    <!--csrf验证需要-->
    <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
    <br/>
    <input type="submit" value="登录">
</form>
</body>
</html>

2、创建Web 安全配置类

@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().csrfTokenRepository(new CookieCsrfTokenRepository())
                .requireCsrfProtectionMatcher(
                        /**
                         * 拦截“/login”开头的访问路径,不让访问
                         * 拦截所有“POST”请求,不让访问
                         */
//                        httpServletRequest -> httpServletRequest.getRequestURI().startsWith("/login")
//                                && httpServletRequest.getMethod().equals("POST")
                        httpServletRequest -> httpServletRequest.getMethod().equals("POST")
                );
    }
}

3、创建Controller

@Controller
public class SecurityController {
    @GetMapping("/login")
    public String login(){
        return "login";
    }
    @GetMapping("/index")
    public String index(){
        return "index";
    }
}

4、案例演示效果
  在我们提交表单的时候,由于请求方法时"POST",所以该请求会被拦截住!

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值