谈谈短信验证码的安全问题

随着手机短信作为身份认证的一种简单有效的手段,短信认证在我们公司系统中的账号注册、密码找回、身份校验中也应用越来越多,随之而来对于短信请求要做的安全防护也越来越重要。

“短信炸弹”缺陷就是最典型的针对短信功能的一种攻击,为了让大家对这种攻击有一个正确的认识,并了解相关的防护手段,我们做了本期的专题讲解。

举个栗子:

下面截图今年上半年公司某系统中曾暴露出的短信炸弹漏洞

第一章:认识“短信炸弹攻击”

概念:短信炸弹攻击,就是攻击者利用站点的短信发送服务向单个手机号码或多个手机号码短时间内发送大量短信的攻击行为。

结果就是这样:

原因说明:如果前端页面上没有对用户请求进行有效保护,服务器端又缺少必要的校验和安全限制,那么就很容易遭受到短信炸弹攻击。

风险说明:浪费公司资源、损害公司声誉,风险中等。防御难度一般。

第二章:防御手段

为了便于大家对防御措施的理解,我们从最基础的防护方案层层递进来讲解:

方案0:既然攻击者要在短时间内发送大量短信,那么就在发送短信的网页上,限制用户点击了发送短信按钮之后,1分钟内无法再次点击。就像下面这样:

方案评估:图样图森破,没有哪个攻击者会用点击按钮的方式进行攻击!这样的防护手段基本上就是掩耳盗铃,攻击者可以通过一万种方式绕过此防护方案。

方案1:既然是防止短时间内发送多条短信的攻击,那么就限制一个手机号码一分钟只能发送1次短信。一天只能发送10次短信。

方案评估:有改进,已经考虑到服务端的安全限制,但是还存在问题:这种限制并不能限制攻击者通过不断修改手机号码的方式消耗短信资源。

方案2:在方案1的基础上,限制攻击者IP,限制每个IP在一分钟内只能发送一次请求。

方案评估:有改进,但意义不大,因为http协议的无状态特性,请求短信的请求数据包是可以修改源IP的,攻击者通过工具自动修改请求数据包中的源IP就可以绕过这种限制。

方案3:在方案1的基础上,加入对SessionID的控制,同一个SessionID的请求在一分钟之内只接受一次短信请求。

方案评估:有较大改进,目前的方案已经能够拦截简单的攻击工具了。但是依然存在问题:攻击者可以循环模拟“获取session ID->发送攻击包"的过程。或者利用DDoS,或者控制肉鸡向服务器发起攻击。

方案4:客户端生成短信请求页面时,服务器端不仅返回一个新的SessionID,而且同时返回一个随机数,客户端请求发送短信时,由客户端向服务器端请求一个回调函数,通过服务器提供的回调方法对请求信息进行加密和签名,从而保证发送短信的请求既不能被破解,又无法被重放。

方案评估:现在的这种方案已经比较成功,能够有效阻断自动化重放工具或试图模拟请求过程的攻击。

但是!攻击者可以绕过这种防护方式,不再理会你做了那些防护措施,而通过模拟浏览器工具,如Selenium模拟页面访问的方式进行自动化攻击。或者通过DDoS的方式,利用肉鸡发起攻击。

方案5:在方案4 的基础上,在页面加入图形验证码,要求发送短信之前先验证短信验证码的内容。

方案评估:验证码是目前比较有效的图灵验证方法,可以有效阻止计算机自动发送的请求数据,从而防止“短信炸弹”攻击,甚至连DDoS这种攻击方式也对此束手无策。

到此为止,我们已经成功的找到短信炸弹攻击的防御方案。

备注:加入验证码的这种方案也是目前防止短信炸弹通用的、最有效的方案。大家可以看一下各个网站发送短信的页面,基本上都有图形验证码。

如下:

金融类需要发送短信的注册页面:

非金融类需要发送短信的页面

相信大家已经对短信炸弹如何防范有了正确的认识,那么问题来了?公司目前系统中发送短信的页面是不是已经做到了这样的安全防护呢?

当然,我们在推行安全控制的时候,一定会有盲目跪舔客户的业务部门人员说:“输入验证码再获取短信验证码不符合客户操作习惯”之类的鬼话。

首先希望我们的需求人员要坚定立场,不接受这种需求!

再其次,如果确实大领导拍板,想要不输入验证码就获取短信,也不是不可操作的,但是要加入更多额外的安全控制措施。

这里就不再讲述具体的解决方式,仅仅举个例子:

平安保险微信报案页面,第一次请求短信是不带验证码的:

再次尝试获取短信,则必须输入验证码:

这里是怎么实现的呢?相信我们开发的小伙伴应该都清楚,我就不做详细解释了。

另外说明:以后这就是我们对发送短信请求页面的安全测试标准,请大家了解。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180126G0SSP300?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券