3

短信接口防盗刷解决方案 - Java知识图谱

 2 years ago
source link: https://www.cnblogs.com/javazhishitupu/p/16134378.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

在Web开发中,总有一些接口需要暴露在用户认证前访问,短信发送接口特别是短信验证码注册接口便是其中典型的一类,这类接口具有如下特点:

  • 流量在用户认证之前

流量在用户认证之前,意味着无法获取用户ID等唯一标识符信息对流量限流

  • 手机号未知

手机号未知意味着无法对待发送短信的手机号做精准检测,判断是否是合法的手机号。通过正则表达式判断手机号连号过多,容易滋生短信盗刷。

本文将重点聚焦接口的防盗刷实践。

二、盗刷流量

在解决防盗刷之前先认识盗刷流量的特点和防盗刷的目标。

(一)防盗刷的目标

1、减少盗刷的总量

如果能将盗刷的频率控制在60秒之外,那么单日盗刷的最大数量为24*60=1440。假如系统入侵者发现请求频率间隔在60秒以上,那么可自动劝退入侵者,原因是投入与产出不匹配。

实际上盗刷流量以秒级甚至毫秒级刷新,对系统造成明显的损害。

2、回避周期性盗刷

周期性盗刷隐匿性更高,对系统有持续破坏能力,积少成多,不易察觉,相比于单次爆破性盗刷,周期性盗刷的危害可能会更大。

对于重要的接口,可考虑动态URL或者给参数增加时间戳签名,避免静态接口被暴露出去。

3、减小对正常用户的影响

防盗刷的重要目标是避免因提高安全等级而误伤正常用户,即使对正常用户有影响,也要减少相应的比率。

(二)盗刷流量的特点

盗刷与正常用户流量有明显区别,尽管盗刷可以模拟正常用户,但是还是通用性区别。

正常用户访问是随机的,失败重试的次数有限并且也是随机的。盗刷流量是周期性的,并且间隔很小。

正常用户是通过浏览器或者APP间接的产生请求流量,盗刷通过代码直接发送HTTP请求。

三、可行性方案

下面通过逐步探究的方式,寻找合适的防盗刷方案。

(一)无安全防护

如果说重要的接口无安全防护措施,那么过于粗心大意。仅靠短信运营商提供的限流和预警方案不能满足短信防盗刷的需求,本质原因是手机号可以合法的模拟,短信运营商不管是正常手机号、停机号、注销号还是尚未投入使用手机号,均会响应发送短信的指令,哪怕是空号发送不成功也会计数。实际上盗刷使用的空号正是接口盗刷的典型特征。

仅靠短信运营商提供的限流和预警方案不能满足短信防盗刷的需求,尽管可以针对单个手机号定制发送短信限额,按小时、按天可定制发送总额,依然不满足短信防盗刷的目标。当触发限流时,正常用户流量同样被限流,对于短信注册来说新增正常用户受影响。如果恶意破坏者连多日耗尽限额短信资源,对正常用户的使用影响很大。

(二)图片验证码

在无防护措施的基础上增加图片验证码,有验证码的保护,短信接口相对安全许多。

短信验证码尽管能够有效保护短信接口防盗刷,但是不能够保护自己被盗刷。盗刷流量恶意刷新图片验证码接口,给服务器CPU造成极大的负载:图片验证码服务与业务耦合,则业务可能响应缓慢;图片验证码服务独立部署,隔离了对业务的影响,但是图片验证码服务器CPU依旧可能过载,正常用户依然收到影响。

Web系统使用图片验证码正逐渐减少,原因是引入了图片验证码保护了短信接口,却无法保护自己。

(三)基于IP限流

上述两种方法存在明显的缺陷,实施落地时几乎不使用,通过基于IP限流无安全防护方案进行升级改造。基于IP地址,每60秒允许发送一条短信(不关联手机号),通过后端强制限流,能够大幅减少短信接口被盗刷的数量。

基于IP限流回避了盗刷模拟手机号的影响,使用IP地址一刀切,稳妥的保证了短信接口的安全。

IP限流有个潜在隐患是如果恶意攻击者与正常用户复用同一个公网IP出口,那么正常用户可能会收到影响,不过这种情况影响范围有限且可控。

恶意盗刷通过代理IP地址仍然能够破解IP限流,只不过增加了破坏者的成本。

UCode CMS内置分布式IP限流的实现,可快速集成到项目中,请访问开源项目中说明文档获取更多内容。

(四)动态请求

通过上述三种方案并没有找到令人满意的防盗刷方案,下面在IP限流的基础上继续打补丁,升级到动态请求。

动态请求的核心思想是将短信验证码接口动态化,既可以接口URL动态化,也可以是参数动态化。下面介绍一种基于时间戳签名参数的方式,实现动态请求。

1、签名参数生成

前后端约定签名参数生成算法,此算法应当保密。

比如:手机号=18612345678,则key=MD5(手机号 + 当前时间/分钟),这里使用60秒的缓冲时间,也可以约定3分钟或者5分钟。

前后端都用这种方式生成key,前端页面通过js脚本生成“签名”,服务端“验签”。
需要注意的是:时间校验要留buffer,客户机时间与服务器时间并不完全相同。

同一个签名参数超过缓冲时间在后端无法实现验签,因此盗刷在不知道签名算法的前提下,盗刷流量有时间维度限制,解决了周期性盗刷的问题。

2、签名算法安全性

签名算法在后端是安全的,出开发人员外,几乎无泄漏的可能。下面着重讨论签名算法在前端的安全性,以Web端和APP端讨论。

(1)Web端

Web端通过JS实现签名算法,由于可通过浏览器直接查看JS,有泄露算法的可能。不过目前大多数JS都是通过压缩处理的,无法直接查看JS的详细内容,如果前端做一些伪装,破坏者找到签名算法有一定难度。

(2)APP端

相比于Web端,APP端的安全性略高,签名拳法封装在APP应用程序中,除非通过反编译手段,无法得知签名算法的详情。

对于非HTTPS流量,可通过抓包程序获取短信接口的URL和参数,在不知道签名算法的前提下,仍不能周期性的盗刷。

上述可行性方案逐步升级,能够实现重要接口的防盗刷需求。

(一)防盗刷建议

对于重要接口的防盗刷,除了使用上述方案外,建议遵循如下要点:

1、使用POST请求

尽量使用POST请求方式,增加盗刷者的尝试成本。

2、使用HTTPS

HTTPS在Web端形同虚设,在APP端有较为很好的保护作用,盗刷者通过抓包工具无法直接获取接口的详情信息,有效的保护了接口。

3、周期性修改接口

随着项目的迭代升级,周期性的随机变更重点接口的请求地址,前后端同步更新。

(二)补充说明

上述可行性讨论方案适用于与短信注册类似的接口。

1、短信登录接口

短信登录在IP限流的基础上增加手机号BitMap检验,如果当前客户端访问IP限流正常,并且当前请求手机号已经注册,则发送短信。

短信登录接口无必要使用复杂的动态请求的方式,原因是已经默认了当前请求手机号存在数据库中,如果不存在那么便是错误请求,快速响应即可。

UCode CMS内置分布式BitMap的实现,可快速集成到项目中,请访问开源项目中说明文档获取更多内容。

2、已认证接口

对于已经经过登录认证的接口,可使用用户ID限流,直接在无安全防护的基础上使用用户ID限流。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK