简介
CSRF漏洞属于客户端攻击, 且需要借助一定的社工手段方可实现攻击, 对于国内的甲方爸爸来说, CSRF的优先级明显低于XSS之类的影响用户的漏洞.
倘若单单是甲方不重视CSRF的防御也就罢了, 可事实是, 甲方往往会收到乙方提供的添加token、验证码、验证referer之类标准答案, 甲方明知有漏洞却迫于开发的抵制无法推动CSRF漏洞的修改. 标准方案在落地的时候总会遇到一些实际情况, 比如: 产品采用前后端分离架构,无法从服务器端下发token、增加验证码会影响用户体验、产品拥有多个域名本身需要跨域、产品有些接口需要被第三方程序调用, 无法设置referer、公司实行有大中台小前台的产品架构
漏洞该业务线修复还是平台修复等种种问题.
为了解决甲方爸爸们的困扰, 特写此CSRF防御方案解决以上提出的问题
文章目录
- owef谈csrf原理
- 最常用的跨域方式
- 不同场景下的CSRF防御方案
owef谈csrf原理
Cross Site Request-forgery, 译为跨站点请求伪造. CSRF是一个知其名便知其意的漏洞, 它的原理是:跨站、伪造客户端请求.
何为跨站, 此处不予以解释, 请自行查阅. 伪造客户端请求这个话题就比较有意思了, 伪造的方式乙方大佬们应该非常清楚, 所以我不谈伪造方式, 谈一个请求可伪造的前提, 1. get请求都可以被伪造; 2. post请求中除了严格使用json格式传输数据的外, 都可以尝试是否可伪造。
当目标站点有了可伪造的请求, 允许跨站调用, 那么它基本上就存在CSRF了.
最常用的跨域方式
当下互联网厂商都在进行架构的调整和转型, 无论是BAT还是新型的中型企业都在做大中台、小前台架构的调整,目的是提高整个企业的产能和效益, 同时当下WEB技术的发展已经进入前端的后辉煌时代, 中型以上规模的互联网企业都在做前后端分离, 这种时代背景下, 多域名、多产品线互相调用的情况是不可避免的, 且大中台负责给小前台提供强有力的平台支撑, 称为PAAS平台. 平台提供给业务线接口自然要负责处理业务线的跨域需求, 于是大部分企业选用了这两种跨域方式:jsonp、cors.
jsonp需要在调用后端接口时传入callback
参数(实际参数名可自行判断获取)来接收服务器返回的数据, 然后通过js函数处理对应的数据. cors跨域需要注意的是Access-Control-Allow-Origin
属性不支持列表形势的参数, 无法传入多个值.
不同场景下的CSRF防御方案
基于上述对CSRF原理的理解和对甲方爸爸们所处现状的分析, owef认为, 在这种场景下如果想搞定CSRF, 必须有PAAS平台来做安全组件, 供小前台调用; 接下来就是分析如何设置适合自己的方案了.
前提工作:
- 分析请求是否易伪造, 是否可更改现有post请求参数为json格式并在后端验证json格式
- 获取公司使用的主域名
场景一: JSONP跨域
JSONP跨域请求是通过js发起调用的, 目前市场上几乎所有的浏览器都不支持通过js修改请求的referer字段, 因此, 通过限制referer可以解决掉大部分的jsonp劫持问题
场景二: 同域调用, 前后端分离
前后端分离的架构下, 无法通过后端分发token, 当然有其他的替代方案来解决, 但是此处讨论最简单的方案, 通过验证referer可以解决前后端分离架构下的大部分CSRF问题
场景三: CORS跨域
CORS跨域是可以带cookie发起请求的, 而真实场景中大部分后端接口也都是需要携带cookie进行访问的, 针对CORS下的CSRF可通过验证origin进行防御
CORS跨域的方案
核心 验证origin、配置Access-Control-Allow-Origin属性
方案
- 收集公司现有的域名
- 创建域名白名单列表
- 根据http request参数匹配白名单列表, 如果存在在服务器端设置Access-Control-Allow-Origin为匹配到的域名; 如果不存在, 服务器端不设置CORS系列的属性.
方案平台化
通过编写python装饰器或django中间处理程序、.net 过滤器等来完成防御方案的编写, 业务线调用对应的接口来对特定的接口实现CSRF防御.