首页 > 基础资料 博客日记
springboot~传统WEB应用开启CSRF
2025-12-31 11:30:01基础资料围观4次
这篇文章介绍了springboot~传统WEB应用开启CSRF,分享给大家做个参考,收藏Java资料网收获更多编程知识
CSRF 是什么?
CSRF(Cross-Site Request Forgery,跨站请求伪造) 是一种常见的Web安全漏洞。攻击者利用受害者已经登录的合法会话,诱使受害者执行非本意的操作。
简单比喻:
想象你在咖啡店会员卡里有钱,你每次消费只需要说“用会员卡支付”。攻击者伪装成服务员,在你面前说“用会员卡转账100元到XXX账户”。因为你已经在咖啡店的系统中“登录”了(身份已认证),系统就会执行这个操作。
CSRF攻击原理:
攻击流程:
- 用户登录:用户登录正常的网站A(如银行网站),获得登录凭证(Cookie/Session)
- 用户访问恶意网站:用户在同一个浏览器中访问了攻击者的网站B
- 恶意请求:网站B通过隐藏表单、图片src、AJAX等方式,向网站A发送请求
- 自动携带凭证:浏览器会自动携带网站A的Cookie
- 网站A执行请求:网站A看到合法Cookie,误以为是用户的自愿操作
攻击示例:
<!-- 恶意网站上的代码 -->
<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 Cookie | Cookie仅在同站请求中发送 | 现代浏览器支持 |
| 双重Cookie验证 | 客户端读取Cookie并附加到请求 | 兼容性较好 |
| Referer检查 | 检查请求来源 | 简单但不可靠 |
| 无(禁用) | 不验证 | 纯API、内部服务 |
何时应该启用/禁用CSRF?
应该启用CSRF的场景:
- ✅ 传统的基于Session的Web应用
- ✅ 用户通过浏览器访问的表单提交
- ✅ 需要用户交互的操作(转账、修改数据)
- ✅ 使用Cookie/Session进行身份认证
可以禁用CSRF的场景:
- ✅ 纯REST API,使用JWT/OAuth Token认证
- ✅ 仅限移动App访问的后端服务
- ✅ 微服务间的内部通信
- ✅ 只读的公共API
- ✅ 使用其他认证方式(API Key、HMAC签名)
禁用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 是否生效
- 检查 Cookie:登录后查看浏览器是否有
XSRF-TOKENCookie - 测试请求:
- 直接发送 POST 请求应该被拒绝(403 错误)
- 携带正确的 CSRF Token 的请求应该成功
- 检查响应头:某些配置下,响应头会包含 CSRF Token
# 使用 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进行身份认证
- 请求来源可控(如仅限移动App、内部服务)
- 已实施同等或更强的安全措施替代
- 确认攻击面不会因此扩大
黄金法则:
如果用户通过浏览器访问你的网站,并且网站使用了Cookie/Session,那么永远不要禁用CSRF保护。只有在完全理解风险并有替代方案时,才考虑为API服务禁用CSRF。
文章来源:https://www.cnblogs.com/lori/p/19425698
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
标签:
上一篇:剑指offer-57、二叉树的下一个节点
下一篇:没有了
相关文章
最新发布
- springboot~传统WEB应用开启CSRF
- 剑指offer-57、二叉树的下一个节点
- 【开源工具分享】一款开源的高效PDF合并与图片转换工具:mergePDF,一款轻量级桌面可视化工具,支持将多个PDF文件合并为单一PDF,也可将PDF转换为图片格式,并提供“单张图片”与“长图片”两种
- 剑指offer-56、删除链表中重复的节点
- jvm~分析gc老年代内存过高的原因
- Java 哪些情况会导致内存泄漏
- Spring AOP + Guava RateLimiter:我是如何用注解实现优雅限流的?
- 回溯算法总结
- Java 操作 Markdown(1)--commonmark-java 使用
- 分库分表数据源ShardingSphereDataSource的Connection元数据误用问题分析

