CSRF防护方案

一些知识要点

这是一个危害不高的漏洞,但是知识点却也不少,有些人只是一知半解,整个漏洞的知识体系都没搞明白,和CORS的漏洞混为一谈,在大厂里搞安全不知道这个细节的也不在少数。

先说一下CSRF的攻击手段,大概就是构造的恶意请求的表单,然后集成在一个恶意url里面,给受害者点击,然后触发请求,就会以受害者的session发送一个请求。

大概整个攻击流程就是这样。

这里面有很重要的一个知识点,就是simple request,这是参考文档:https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

简单说,就是满足这个简单请求的,就不用要求跨域,这个跨域CORS我就不多解释了,如果这个没搞懂,那CSRF这个也搞不懂了。

所以,这些构造的攻击表单,都是满足简单请求这个条件。当服务端只允许接受content-type是json情况下,还能构造CSRF攻击吗?

有人说能,用XMLHttpRequest,把content-type改成json就好了……. 但是这个不满足simple request的条件,在没有CORS的问题下是无法攻击成功的。所以服务端防御CSRF,只需要强制校验content-type。

防护方案

根据上面说的,校验content-type就好了,但是因为一些历史的原因,前端已经使用了form表单的格式,端上也是用的form表单的格式,那怎么办。如果调用方式都改成json的数据格式,成本太高。由此,就开发了一个防护方案,这个方案的主要防护原理以下几点:

  • 服务端前的网关层做token校验
  • 浏览器前端层面做请求hook,把请求都带上token,发送请求前,先去网关那里获取一个token

这里说下前端的hook,就是prototype的属性重新赋值,把原先那个函数的值保存下来,然后在重新赋值时,带上token,再把原来的函数最后执行

实现这个主要是以下这些开发工作:

  • 前端SDK开发
  • 后端网关token服务开发

整个请求流程变成如下:

  1. 前端sdk,请求获取token,后端网关层返回token
  2. 正常的请求携带上token
  3. 后端网关校验token

这里面有一点必不可少的就是校验origin。

最后

说实话,修复的时候,既要前端接入sdk,又要后端接入网关

实际上不如在开发时候就直接限制好content-type是json这个要求。