Spring Boot实现CSRF保护后,其抵御CSRF攻击的原理是什么?
Spring Boot CSRF保护实现的防攻击机制解析
你的实现运行流程
- 首次通过Basic Auth完成用户认证后,服务端会在响应Cookie中返回
jsessionid(会话标识)和xsrf-token(CSRF令牌) - 后续发起POST、PUT等修改类请求时,只要携带相同的
jsessionidCookie,同时在请求头(或请求参数)中携带正确的xsrf-token,就能通过服务端的认证校验
该机制如何抵御CSRF攻击
CSRF攻击的核心逻辑是:攻击者诱导已登录的用户访问恶意站点,浏览器会自动携带用户的登录Cookie(包括jsessionid)向你的服务端发起请求,而用户完全不知情。你的实现正是通过以下逻辑切断了这种攻击路径:
绑定会话的随机令牌校验
服务端生成的xsrf-token是和用户当前会话(jsessionid)绑定的随机值,攻击者无法提前预知或获取到这个值。因为浏览器的同源策略限制,恶意站点无法读取你的域名下的xsrf-tokenCookie内容,也就无法在伪造的请求中携带正确的令牌。双重存储与校验逻辑
你使用的CookieCsrfTokenRepository会把生成的CSRF令牌同时存在两个地方:- 存储在用户的会话(Session)中,用于服务端做校验对比
- 存储在非HttpOnly的Cookie中,让前端可以通过JavaScript读取到这个令牌
当你发起修改类请求时,必须在请求头(比如X-XSRF-TOKEN)或请求参数中携带这个令牌,服务端会将请求中的令牌和会话中存储的令牌做比对,不一致则直接拒绝请求。
CsrfCookieFilter的辅助作用
这个过滤器会在Basic认证完成后,把CSRF令牌写入响应头中,方便前端直接从响应头获取令牌(比从Cookie读取更便捷),本质是优化前端获取令牌的方式,不影响核心的校验逻辑。合理的豁免规则
配置中ignoringRequestMatchers("/contact", "/register")对不需要用户登录的公开接口关闭了CSRF保护,这类接口本身不存在用户身份被冒用的风险,豁免后不会影响安全性,还能降低不必要的校验开销。
你的代码实现
// CSRF配置实现 CsrfTokenRequestAttributeHandler attributeHandler = new CsrfTokenRequestAttributeHandler(); attributeHandler.setCsrfRequestAttributeName("_csrf"); .csrf(csrf -> csrf.csrfTokenRequestHandler(attributeHandler) .ignoringRequestMatchers("/contact", "/register") .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())) .addFilterAfter(new CsrfCookieFilter(), BasicAuthenticationFilter.class) public class CsrfCookieFilter extends OncePerRequestFilter{ @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { CsrfToken csrfToken = (CsrfToken) request.getAttribute(CsrfToken.class.getName()); if(null != csrfToken.getHeaderName()){ response.setHeader(csrfToken.getHeaderName(), csrfToken.getToken()); } filterChain.doFilter(request, response); } }
内容的提问来源于stack exchange,提问作者utkarsh sharma
相关产品推荐
相关产品推荐

