java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > springboot开启csrf

SpringBoot传统WEB应用开启CSRF的流程

作者:张占岭

CSRF是一种Web安全漏洞,攻击者利用受害者合法会话诱使执行非本意操作,文章介绍了CSRF的攻击原理、适用禁用场景以及Spring Security和Django中的禁用示例,同时,对比了不同CSRF保护机制的工作原理和适用场景,感兴趣的朋友跟随小编一起看看吧

CSRF 是什么?

CSRF(Cross-Site Request Forgery,跨站请求伪造) 是一种常见的Web安全漏洞。攻击者利用受害者已经登录的合法会话,诱使受害者执行非本意的操作。

简单比喻:

想象你在咖啡店会员卡里有钱,你每次消费只需要说“用会员卡支付”。攻击者伪装成服务员,在你面前说“用会员卡转账100元到XXX账户”。因为你已经在咖啡店的系统中“登录”了(身份已认证),系统就会执行这个操作。

CSRF攻击原理:

攻击流程:

攻击示例:

<!-- 恶意网站上的代码 -->
<img src="https://your-bank.com/transfer?to=hacker&amount=10000" width="0" height="0" />
<!-- 或隐藏表单 -->
<form action="https://your-bank.com/change-email" method="POST">
  <input type="hidden" name="email" value="hacker@evil.com">
</form>
<script>document.forms[0].submit();</script>

为什么有时要禁用CSRF保护?

适用禁用场景:

纯API服务(无浏览器交互)

# 移动App通过API访问后端
# 使用Token认证(JWT/OAuth),而不是Session
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

仅提供非状态改变的操作

GET /api/users          # 只读操作,通常不需要CSRF
POST /api/transfer      # 写操作,需要CSRF

微服务内部通信

# 服务间调用使用服务凭证,而不是用户会话
service-to-service: true

某些特殊框架/场景

// GraphQL通常使用token而不是session
// 或某些实时通信应用

具体框架中的禁用示例:

Spring Security:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()  // 禁用CSRF
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .httpBasic();  // 使用HTTP Basic认证
    }
}

Django:

# settings.py
CSRF_COOKIE_SECURE = False  # 禁用CSRF
# 或针对特定视图
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def api_view(request):
    pass

CSRF保护机制对比:

保护机制工作原理适用场景
CSRF Token服务器生成Token,表单/请求必须携带传统Web应用
SameSite CookieCookie仅在同站请求中发送现代浏览器支持
双重Cookie验证客户端读取Cookie并附加到请求兼容性较好
Referer检查检查请求来源简单但不可靠
无(禁用)不验证纯API、内部服务

何时应该启用/禁用CSRF?

应该启用CSRF的场景:

可以禁用CSRF的场景:

禁用CSRF后的替代安全方案:

# 替代方案示例:
1. JWT Token认证:
   每次请求携带: Authorization: Bearer <token>
2. API Key + Secret:
   请求签名: X-Signature: sha256(api_secret + request_data)
3. OAuth 2.0:
   使用Access Token进行授权
4. CORS限制:
   Access-Control-Allow-Origin: https://trusted-domain.com
5. Rate Limiting:
   限制请求频率防止滥用

最佳实践建议:

// 在Spring中,可以针对不同端点配置不同的CSRF策略
public class SecurityConfig {
    protected void configure(HttpSecurity http) {
        http
            // 对Web页面启用CSRF
            .csrf(csrf -> csrf
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                .csrfTokenRequestHandler(new CsrfTokenRequestAttributeHandler())
            )
                .requireCsrfProtectionMatcher(
                    new RequestMatcher() {
                        public boolean matches(HttpServletRequest request) {
                            // 仅对特定路径启用CSRF
                            return request.getRequestURI().startsWith("/web/");
                        }
                    })
            .and()
            // API端点使用无状态认证
            .authorizeRequests()
                .antMatchers("/api/**").authenticated()
                .and()
            .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS); // API无状态
    }
}

验证 CSRF 是否生效

# 使用 curl 测试
# 1. 先获取 CSRF Token(从登录后的 Cookie 或响应头)
# 2. 发送带 CSRF Token 的请求
curl -X POST http://localhost:8080/api/test \
  -H "Content-Type: application/json" \
  -H "X-XSRF-TOKEN: YOUR_CSRF_TOKEN" \
  -H "Cookie: XSRF-TOKEN=YOUR_CSRF_TOKEN" \
  -d '{"data": "test"}'

总结:

禁用CSRF的前提条件:

黄金法则:

如果用户通过浏览器访问你的网站,并且网站使用了Cookie/Session,那么永远不要禁用CSRF保护。只有在完全理解风险并有替代方案时,才考虑为API服务禁用CSRF。

到此这篇关于springboot~传统WEB应用开启CSRF的文章就介绍到这了,更多相关java多线程内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文