🥇 CSRF的定义

跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。跟跨站站指令码(XSS)相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。
简单点说,CSRF 就是利用用户的登录态发起恶意请求。

🥇 通过一个故事来介绍csrf

防盗系统启动
妈妈:给我看着衣服呀
小孩:好的

小偷来了
正常工作:
小孩:你是谁?
小偷:我是张三
小孩:妈妈,有人偷衣服
妈妈:谁?
小孩:张三
小偷被抓

漏洞:
小孩:你是谁?
小偷:我叫逗你玩
小孩:妈妈有人偷衣服呀
妈妈:谁?
小孩:逗你玩
妈妈:…
csrf 是让用户住不知情的情况下,冒用其身份发起了一个请求

🥇 如何攻击

image.png
从上图可以看出,要完成一次CSRF攻击,受害者必须依次完成两个步骤:

  1. 1. 登录受信任网站A,并在本地生成Cookie
  2. 2. 在不登出A的情况下,访问危险网站B

  看到这里,你也许会说:“如果我不满足以上两个条件中的一个,我就不会受到CSRF的攻击”。是的,确实如此,但你不能保证以下情况不会发生:

  1. 1. 你不能保证你登录了一个网站后,不再打开一个tab页面并访问另外的网站。
  2. 2. 你不能保证你关闭浏览器了后,你本地的Cookie立刻过期,你上次的会话已经结束。(事实上,关闭浏览器不能结束一个会话,但大多数人都会错误的认为关闭浏览器就等于退出登录/结束会话了......)
  3. 3. 上图中所谓的攻击网站,可能是一个存在其他漏洞的可信任的经常被人访问的网站。

🥈 例子

假如一家银行用以运行转账操作的URL地址如下:http://www.examplebank.com/withdraw?account=AccoutName&amount=1000&for=PayeeName
那么,一个恶意攻击者可以在另一个网站上放置如下代码: 什么是 CSRF 攻击 - 图2](http://www.examplebank.com/withdraw?account=Alice&amount=1000&for=Badman">)
如果有账户名为Alice的用户访问了恶意站点,而她之前刚访问过银行不久,登录信息尚未过期,那么她就会损失1000资金。
这种恶意的网址可以有很多种形式,藏身于网页中的许多地方。此外,攻击者也不需要控制放置恶意网址的网站。例如他可以将这种地址藏在论坛,博客等任何用户生成内容的网站中。这意味着如果服务端没有合适的防御措施的话,用户即使访问熟悉的可信网站也有受攻击的危险。
透过例子能够看出,攻击者并不能通过CSRF攻击来直接获取用户的账户控制权,也不能直接窃取用户的任何信息。他们能做到的,是欺骗用户浏览器,让其以用户的名义运行操作。

🥇 CSRF 的防御

CSRF的防御可以从服务端和客户端两方面着手,防御效果是从服务端着手效果比较好,现在一般的CSRF防御也都在服务端进行。
防范 CSRF 可以遵循以下几种规则:

  1. 1. Get 请求不对数据进行修改
  2. 2. 不让第三方网站访问到用户 Cookie
  3. 3. 阻止第三方网站请求接口
  4. 4. 请求时附带验证信息,比如验证码或者 token

🥈 SameSite

可以对 Cookie 设置 SameSite 属性。该属性设置 Cookie 不随着跨域请求发送,该属性可以很大程度减少 CSRF 的攻击,但是该属性目前并不是所有浏览器都兼容。

🥈 验证 Referer

对于需要防范 CSRF 的请求,我们可以通过验证 Referer 来判断该请求是否为第三方网站发起的。
在后台接收到请求的时候,可以通过请求头中的 Referer 请求头来判断请求来源

🥈 Token

服务器下发一个随机 Token(算法不能复杂),每次发起请求时将 Token 携带上,服务器验证 Token 是否有效。