本文最后更新于:2025年2月18日 下午
解决cookie中无samesite的漏洞和无反CSRF设置的漏洞
SpringBoot2.6.0之后可直接在配置文件中设置
1 2 3 4 5 6 7 8
| server: servlet: session: cookie: same-site: LAX
|
以下为2.6.0之前
服务器会默认自动生成一个cookie
,其中属性为JSESSIONID
,这个是没有指定samesite
。
解决方法是自己实现生成一个防止CSRF的cookie属性,并设置上samesite
。这样自动生成的这个我们不用,也不做验证,就可以直接忽略掉了。
例如在网站入口处生成,以下以springboot的thymeleaf控制方法演示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @GetMapping("login") public String toLogin(HttpSession session,HttpServletResponse response) { String csrf_id = UUID.randomUUID().toString().replace("-", ""); String s = PasswordUtil.hashPassword(csrf_id); session.setAttribute("XSRF-TOKEN", s); ResponseCookie cookie = ResponseCookie.from("XSRF-TOKEN", csrf_id) .sameSite("Strict") .maxAge(604800) .path("/") .httpOnly(true) .secure(true) .build(); response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString()); return "login"; }
|
在拦截器内进行验证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| Cookie[] cookies = request.getCookies(); for (Cookie cookie : cookies) { if (cookie.getName().equals("XSRF-TOKEN")) { if (cookie.getValue() != null) { HttpSession session = request.getSession(false); if (session != null) { String csrf = (String) session.getAttribute("XSRF-TOKEN"); if (csrf == null || csrf.isEmpty()) { System.out.println("csrf为空"); return false; }
boolean csrfValid = PasswordUtil.checkPassword(cookie.getValue(), csrf); System.out.println("验证CSRF!"); if (!csrfValid) { return false; } } else { System.out.println("Session 不存在"); return false; } } } }
|