CSRF整理
字数 1434 2025-08-15 21:31:44
CSRF(跨站请求伪造)攻击与防御全面解析
1. CSRF基本概念
CSRF(Cross-Site Request Forgery,跨站请求伪造)是一种利用用户已登录的身份,在用户不知情的情况下执行非预期操作的攻击方式。
1.1 CSRF攻击原理
- 攻击者诱导受害者访问恶意网页
- 该网页包含针对目标网站的请求(如转账、修改密码等)
- 浏览器会自动携带受害者的身份凭证(如Cookie)发送请求
- 服务器无法区分这是用户自愿操作还是伪造请求
1.2 CSRF攻击条件
- 用户已登录目标网站
- 目标网站没有有效的CSRF防护措施
- 用户访问了攻击者构造的恶意页面
- 目标操作可以通过简单请求(GET/POST)完成
2. CSRF攻击类型
2.1 GET型CSRF
- 利用GET请求的特性,通过img等标签自动发起请求
- 常见于浏览器会自动加载的资源请求
2.2 POST型CSRF
<form action="http://bank.com/transfer" method="POST" id="csrf">
<input type="hidden" name="to" value="attacker">
<input type="hidden" name="amount" value="10000">
</form>
<script>document.getElementById('csrf').submit();</script>
- 构造隐藏表单,通过JavaScript自动提交
- 需要目标操作使用POST方法
2.3 其他变种
- JSON CSRF:针对API接口的CSRF攻击
- Flash CSRF:利用Flash发起跨域请求
- 文件上传CSRF:利用文件上传功能绕过防护
3. CSRF攻击危害
- 账户劫持:修改密码、邮箱等
- 资金损失:转账、消费等
- 数据泄露:导出数据、授权第三方等
- 系统破坏:删除内容、修改配置等
4. CSRF防御措施
4.1 验证HTTP Referer头
- 检查请求来源是否合法
- 缺点:Referer可能被篡改或缺失
4.2 使用CSRF Token
实现方式:
- 服务器生成随机Token
- 将Token嵌入表单或HTTP头
- 提交时验证Token有效性
Token设计要点:
- 足够随机(加密强度随机数)
- 绑定用户会话
- 一次性使用或短有效期
- 不要通过Cookie传输
4.3 双重Cookie验证
- 请求时从Cookie中提取Token
- 将Token放入请求头或表单参数
- 服务器验证两者是否一致
4.4 SameSite Cookie属性
Set-Cookie: sessionid=xxxx; SameSite=Strict
- Strict:完全禁止第三方Cookie
- Lax:宽松模式,允许部分安全请求
- None:关闭SameSite保护(需配合Secure)
4.5 关键操作二次验证
- 密码确认
- 短信/邮箱验证码
- 生物识别验证
5. 高级防护技术
5.1 自定义HTTP头
// 前端设置
xhr.setRequestHeader('X-CSRF-Token', token);
- 配合CORS策略使用
- 适用于AJAX请求
5.2 验证码防护
- 关键操作要求输入验证码
- 增加自动化攻击难度
5.3 请求限速
- 限制单位时间内的操作频率
- 防止自动化攻击
6. 常见框架的CSRF防护
6.1 Django
# settings.py
MIDDLEWARE = [
'django.middleware.csrf.CsrfViewMiddleware',
]
# 模板中
<form method="post">{% csrf_token %}</form>
6.2 Spring Security
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
}
6.3 Laravel
// Blade模板
<form method="POST" action="/profile">
@csrf
...
</form>
7. CSRF测试方法
- 检查关键操作是否有CSRF Token
- 验证Token是否随机且唯一
- 测试移除Token后请求是否仍然有效
- 检查SameSite Cookie设置
- 验证Referer检查是否可绕过
8. 实际案例分析
8.1 银行转账CSRF
<!-- 恶意页面 -->
<body onload="document.forms[0].submit()">
<form action="https://bank.com/transfer" method="POST">
<input type="hidden" name="amount" value="10000">
<input type="hidden" name="to" value="attacker_account">
</form>
</body>
漏洞原因:转账接口未验证CSRF Token
8.2 密码修改CSRF
漏洞原因:使用GET方法处理敏感操作
9. 最佳实践总结
- 对所有状态修改请求实施CSRF防护
- 优先使用CSRF Token + SameSite Cookie组合
- 敏感操作增加二次验证
- 避免使用GET方法进行状态修改
- 定期进行安全测试和代码审计
通过全面实施这些防护措施,可以有效地防范CSRF攻击,保护用户和系统的安全。