跨站请求伪造CSRF (Cross Site Request Forgery):是一种利用用户身份认证漏洞,骗取服务器信任,让受害者在不知情的情况下,执行攻击者指定的恶意请求。
攻击原理
- 用户登录A网站,浏览器保存了用于身份认证的Cookie。
- 攻击者诱导用户访问B网站。
- B网站"静悄悄"地向A网站发送请求,浏览器自动携带用户的Cookie进行身份认证。
- 用户账号被攻击者"控制",例如转账、删除资源等。
示例
用户在 meow.com
登录账号(此时Cookie仍然有效)
攻击者在自己的钓鱼网站上嵌入了一张恶意图片:
html
<img src="https://meow.com/transfer?to=attacker&amount=5000">
或构造一个form表单,然后利用Javascript自动提交
html
<p>只是和你开个小玩笑👿,新年快乐🎉</p>
<form id="myForm" action="https://meow.com/transfer">
<input type="hidden" name="to" value="attacker">
<input type="hidden" name="amount" value="5000">
</form>
<script>
document.getElementById('myForm').submit()
</script>
用户访问后链接后,浏览器会自动带上会话数据(Cookie),导致用户的账户向攻击者转账!
防御
- 二次认证:在进行某些关键操作时(如转账、删除用户),要求用户进行二次登录或者输入验证。
- 设置
sameSite=Strict
,限制Cookie只能在同源站点提交,防止跨站滥用。
Koa
设置Cookie 的SameSite属性:
javascript
ctx.cookies.set('sessionId', sessionId, {
path: '/',
httpOnly: true,
secure: false,
sameSite: 'strict',
})
- Token认证:服务器生成随机的Token,并在表单或请求中携带,服务器在收到请求时验证Token。
前端提交服务器返回的CSRF Token:
html
<form method="POST" action="https://meow.com/login">
<input type="hidden" name="_csrf" value="token">
<input type="submit" value="登录">
</form>