乐趣区

关于前端:CSRF攻击原理与常见解决方案

什么是 CSRF

跨站申请伪造(Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF,是一种挟制用户在以后已登录的 Web 上执行非本意的操作的攻打办法。

简略来说,就是冒用你的登录信息,以你的名义发送歹意申请。

原理

  1. 用户 A 登录了本人罕用的网站 www.yinhang.com, 登录胜利后,cookie 中会蕴含 A 的 登录信息
  2. 骗子 利用广告或者链接等诱导你关上网站 www.jiamao.com。该网站中会利用 form 表单或者其余形式,向网站 www.yinhang.com 发送申请,网站的接口申请格局个别很容易获取到,例如 www.yinhang.com/api/zhuanzhang?account=A&count=10000&to=pianzi 发送的申请会主动携带上 www.yinhang.com 的 cookie 信息,即你的身份验证信息
  3. 服务器端在收到申请后,测验身份信息是正确的,而后整个攻打就实现了

常见解决方案

referer 首部

在 request header 中,有个 referer 字段,表明申请的起源,服务端能够通过这个字段判断是否是在非法的网站下发送的申请。

缺点:Referer 的值是由浏览器提供的,不同的浏览器实现不同,无奈确保某些浏览器是否有安全漏洞,导致能够自行批改 Referer 字段

表单 token 检测

由服务端生成一个 token,返回给前端,在每次发送申请中,在参数中额定加入一个参数,例如 _csrf_token , 服务端每次校验时比照 _csrf_token 与服务端存储的值。

fetch(path, {
    ...otherParam,
    _csrf_token: 'token_value'
});

或者服务端返回的表单页面中暗藏 _csrf_token 值

<form method="POST" action="/upload" enctype="multipart/form-data">
    <input name="_csrf_token" value="{{由服务端生成}}" style="display: none" />
    用户名: <input name="name" />
    <button type="submit"> 提交 </button>
</form>

缺点:须要手动传递参数值,比拟冗余麻烦,额定的参数字段也没有业务意义

header 中减少 csrf_token

由后端生成 csrf_token 设置在 cookie 中,前端获取到 token 后设置在 header 中,能够对立在封装 request 办法时写入,例如


let csrfToken = Cookies.get('csrfToken');

$.ajaxSetup({beforeSend: function(xhr, settings) {xhr.setRequestHeader('x-csrf-token', csrfToken);
  }
});

留个思考,csrf 个别都是跨网站的,按理应该都会有跨域限度,所以申请是怎么收回去的呢。

猜测 1: 网站应用了 cors 跨域拜访,但对域名未加限度
猜测 2: 某些浏览器并不能对跨域做良好的限度

退出移动版