CSRF
# CSRF
# 什么是 CSRF
CSRF:Cross-site request forgery 跨站请求伪造
- 本质上是钓鱼
- 攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求
- 利用受害者在被攻击网站已经获取的登录凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的
原理:
一个典型的 CSRF 攻击有着如下的流程:
- 受害者登录 a.com,并保留了登录凭证(Cookie)
- 攻击者引诱受害者访问了 b.com
- b.com 向 a.com 发送了一个请求:a.com/act=xx,浏览器会默认携带 a.com 的 Cookie
- a.com 接收到请求后,对请求进行验证,并确认是受害者的凭证,误以为是受害者自己发送的请求
- a.com 以受害者的名义执行了 act=xx
- 攻击完成,攻击者在受害者不知情的情况下,冒充受害者,让 a.com 执行了自己定义的操作
# CSRF 攻击方式
# get 请求产生的 CSRF
有 href 和 HTTP 请求两种方式
# href 攻击的方式
<a href="http://bank.com/transfer?account_number_from=123456789&account_number_to=987654321&amount=100000">View my Pictures!</a>
1
- 已经登录了bank.com
- 点击 "View my Pictures" 这一链接时,会将钱从一个账户转移到另一个账户,数额为 100000
# HTTP 请求方式
<img src="http://bank.example/withdraw/account=xiaoming&amount=10000&for=hacker" />
1
- 受害者访问含有这个 img 的页面后,浏览器会自动向 http://bank.example/withdraw/account=xiaoming&amount=10000&for=hacker 发出一次 HTTP 请求
- 在攻击者接收到请求的时候我们便可以“借用”对方的 Cookie
# post 请求产生的 CSRF
- post 请求所产生的 CSRF 是利用地最多的攻击方式
- 这种类型的 CSRF 通常利用的是一个自动提交的表单
<form action="http://bank.example/withdraw" method=POST>
<input type="hidden" name="account" value="xiaoming" />
<input type="hidden" name="amount" value="10000" />
<input type="hidden" name="for" value="hacker" />
</form>
<script> document.forms[0].submit(); </script>
1
2
3
4
5
6
2
3
4
5
6
访问该页面后,表单会自动提交,相当于模拟用户完成了一次 POST 操作
# CSRF 的防御手段
主流的 CSRF 防御手段有以下两种:
- 使用同源检测与 Samesite Cookie
- 多加一层验证手段 CSRF Token
# CSRF Token
工作原理:
- CSRF Token 每随着页面被操作,比如 f5 刷新,点击按钮等等,都会导致 CSRF Token 变化
- 每一个请求的 CSRF Token 会通过后端代码验证 Token 是否正确,在时间戳上是否有效,如果加密字符串一致且时间未过期,那么这个 Token 就是有效的
# 限制同源
通过设置 Set-Cookie 的值
# Strict
- Strict 最为严格,完全禁止第三方 Cookie
- 跨站点时,任何情况下都不会发送 Cookie
- 只有当前网页的 URL 与请求目标一致,才会带上 Cookie
Set-Cookie: CookieName=CookieValue; SameSite=Strict;
1
# Lax
- Lax 规则稍稍放宽,大多数情况也是不发送第三方 Cookie
- 导航到目标网址的 Get 请求除外
Set-Cookie: CookieName=CookieValue; SameSite=Lax;
1
# None
- 代表关闭了 SameSite
- 一般攻击要进行绕过可以尝试将 SameSite 设置为 None
Set-Cookie: CookieName=CookieValue; SameSite=None;
1