当前位置: 首页 > news >正文

跨站点请求伪造(CSRF)原理与Spring Security防护机制详解

跨站点请求伪造(CSRF)原理与Spring Security防护机制详解

在这里插入图片描述


CSRF攻击原理

攻击者诱导已登录用户访问恶意页面,利用用户当前会话的Cookie权限,向目标网站发送恶意请求(如转账、修改密码等)。例如:

  1. 用户登录了银行网站(已携带有效Cookie)。

  2. 用户访问攻击者伪造的页面,该页面包含一个隐藏的表单:

    <form action="https://bank.com/transfer" method="POST">
      <input type="hidden" name="amount" value="10000">
      <input type="submit" value="领取优惠">
    </form>
    
  3. 用户被诱导点击提交,银行服务器误认为是合法请求,执行转账。


Spring Security如何防御CSRF

Spring Security通过 CSRF令牌机制 实现防护,核心步骤如下:

  1. 生成令牌:在用户会话中生成唯一CSRF令牌(存储在Cookie或Session中)。
  2. 表单嵌入令牌:在每个POST/PUT/DELETE请求的表单中添加隐藏字段,值为当前令牌。
  3. 验证令牌:服务器端对请求的令牌进行校验,若不匹配则拒绝请求。

完整代码示例

以下代码展示如何在Spring Boot中配置CSRF防护,并通过表单和AJAX请求验证其有效性。


1. Spring Security配置类
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // 启用CSRF防护(默认已启用,可显式配置)
            .csrf(csrf -> csrf
                .requireCsrfProtectionMatcher(request -> {
                    // 自定义需要CSRF保护的请求路径(示例:所有POST请求)
                    return request.getMethod().equals("POST");
                })
                .ignoringAntMatchers("/api/public") // 排除特定路径(如公开API)
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) // 允许通过JS访问CSRF令牌
            )
            .authorizeRequests()
                .antMatchers("/login").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .permitAll();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        return username -> {
            if ("user".equals(username)) {
                return User.withUsername("user")
                    .password("{noop}password")
                    .roles("USER")
                    .build();
            }
            return null;
        };
    }
}

2. 表单页面(Thymeleaf示例)
<!-- login.html -->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Login</title>
</head>
<body>
    <form method="post" action="/login">
        <input type="text" name="username" placeholder="Username" required>
        <input type="password" name="password" placeholder="Password" required>
        <button type="submit">Login</button>
        <!-- 自动添加CSRF令牌字段 -->
        <input type="hidden" 
               name="_csrf" 
               th:value="${_csrf.token}">
        <input type="hidden" 
               name="_csrf_header" 
               th:value="${_csrf.headerName}">
    </form>
</body>
</html>

3. 受保护的POST接口
@RestController
public class UserController {

    @PostMapping("/profile/update")
    public String updateProfile(
            @RequestParam String username,
            @RequestParam String email,
            @CsrfTokenRequestAttribute CsrfToken csrf) {
        // 验证逻辑(Spring Security已自动校验CSRF令牌)
        return "Profile updated successfully";
    }
}

4. AJAX请求示例(JavaScript)
// 从Cookie中获取CSRF令牌(需确保Cookie可访问)
function getCookie(name) {
    const value = `; ${document.cookie}`;
    const parts = value.split(`; ${name}=`);
    if (parts.length === 2) return parts.pop().split(';').shift();
}

const csrfToken = getCookie('XSRF-TOKEN');

fetch('/profile/update', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'X-XSRF-TOKEN': csrfToken // 添加CSRF令牌到请求头
    },
    body: JSON.stringify({ username: 'user', email: 'user@example.com' })
});

关键配置说明
  1. CSRF令牌存储

    • 默认存储在Cookie(XSRF-TOKEN)和Session中。
    • CookieCsrfTokenRepository允许前端通过JavaScript读取令牌。
  2. 表单自动注入

    • Thymeleaf模板中通过_csrf对象自动添加隐藏字段。
    • Spring Security会自动校验请求中的令牌。
  3. 自定义规则

    • requireCsrfProtectionMatcher:指定需要CSRF保护的请求方法或路径。
    • ignoringAntMatchers:排除不需要防护的公开API。

测试CSRF防护
  1. 正常请求

    • 提交表单或携带有效令牌的AJAX请求,返回成功。
  2. 伪造请求

    • 使用Postman发送POST请求,未携带CSRF令牌:

      POST /profile/update
      Content-Type: application/json
      Body: { "username": "attack" }
      
    • 响应状态码:403 Forbidden(被拦截)。


总结表格
配置项描述默认行为
CSRF防护需要显式配置(默认已启用)启用
令牌存储位置Cookie(XSRF-TOKEN)和SessionCookie + Session
保护的HTTP方法POST/PUT/PATCH/DELETE支持所有非安全方法
前端集成方式表单隐藏字段或AJAX请求头(X-XSRF-TOKEN自动注入
排除路径通过ignoringAntMatchers配置

通过上述配置,Spring Security能够有效防御CSRF攻击,同时提供灵活的扩展性以适应不同业务场景。

相关文章:

  • 数据结构|排序算法(二)插入排序 希尔排序 冒泡排序
  • gerrit上面可以git fetch
  • P8697 [蓝桥杯 2019 国 C] 最长子序列
  • conda-pack打包环境到超算上。解决无法打包可编辑包
  • GIS开发笔记(3)win11环境中osgearth加载大体积全球高程数据(dem)
  • 以太网供电(PoE)交换机:为音频和视频系统赋能的多面利器
  • 探索安固软件:保护您的电子文档安全
  • 探秘 MQTT 协议:物联网的 “隐形桥梁”
  • Java面试43-常见的限流算法有哪些?
  • MySQL5.7数据库部署和安装
  • cesium项目之cesiumlab地形数据加载
  • 设计模式:依赖倒转原则 - 依赖抽象,解耦具体实现
  • UI测试流程与关键注意点解析
  • LLMs基础学习(七)DeepSeek专题(1)
  • 我的计算机网络(总览篇)
  • BERT - MLM 和 NSP
  • 2025最新数字化转型国家标准《数字化转型管理参考架构》 正式发布
  • 蓝桥杯python组备考3(b站课程笔记)超详细
  • Mac学习使用全借鉴模式
  • Java实现音频录音播放机功能
  • wordpress添加vip用户组/外贸seo网站
  • 网站建设基本流程是什么/如何推广引流
  • 马关网站建设/做一个推广网站大概多少钱
  • 做百度手机网站点击/西安关键词seo
  • 网站制作公司商丘市/seo网络搜索引擎优化
  • 2022最新国内新闻50条简短/中山口碑seo推广