技术分享 CSRF

CSRF,Cross-Site Request Forgery,跨站请求伪造。

一、什么是 CSRF 攻击?

CSRF 攻击,即跨站请求伪造攻击,简单来说,攻击者以用户的名义发送恶意请求。

二、CSRF 攻击流程

  • 用户正在网站 A 中登录,浏览器存储了网站 A 的 Cookie
  • 在没有登出网站 A 的情况下,访问恶意网站 B
  • 浏览器在恶意网站 B 的要求下,向网站 A 发出请求,该请求将会自动携带 Cookie,从而恶意网站实现了冒用用户名义发送请求的目的

三、CSRF 攻击示例

1. GET 类型

恶意网站中包含代码片段:

1
<img src="http://www.mybank.com/transfer?toBankId=11&money=1000">

浏览器打开恶意网站后,将会尝试解析图片,从而发送一个类型为 GET 的转账请求。

2. POST 类型

恶意网站中包含代码片段:

1
2
3
4
5
6
<form action="http://www.mybank.com/transfer" 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>

浏览器打开恶意网站后,表单将会自动提交,从而发送了一个类型为 POST 的转账请求。

3. 链接类型

1
<a src="http://www.mybank.com/transfer?toBankId=11&money=1000">

四、CSRF 攻击的防护

1. 同源检测

服务器端可以检查 HTTP 请求头中的 origin 或 referer 信息,它记录了 HTTP 请求的来源地址,可以通过它来判断请求是否由可信的站点发出。

这一方法的好处是:简单易行,只需要给敏感的请求统一增加一个拦截器做简单校验即可。

可以设置 Cookie 的 same-site 属性,限制它在跨站点时的发送行为。

same-site 属性可以设置如下:

  • Strict:最严格,不会在跨站点时发送 cookie

    只有当前网页的 url 和请求目标一致,才会带上 cookie

  • Lax:较为严格,不会发送第三方 cookie,除非是导航到其它目标的 get 请求

  • None:关闭 same-site 属性,但前提是必须同时设置 secure 属性(cookie 只能通过 https 协议发送)

3. 额外参数

要求请求时附带额外参数,例如:

  • 把 cookie 同步放到 header / 请求参数中
  • 在请求之前,应该预先发送另外一个请求获取 token,并将其放到 header / 请求参数中

攻击所在网页无法获取 cookie、无法预知 token,因此自然无法构造出满足要求的 img、a、form,自然无法通过校验。

4. 特殊验证码

对于敏感请求,可以通过增加短信验证码、图形化验证码的方式,要求用户做二次确认。

参考