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服务开发
整个请求流程变成如下:
- 前端sdk,请求获取token,后端网关层返回token
- 正常的请求携带上token
- 后端网关校验token
这里面有一点必不可少的就是校验origin。
最后
说实话,修复的时候,既要前端接入sdk,又要后端接入网关
实际上不如在开发时候就直接限制好content-type是json这个要求。