短信防刷机制设计

短信验证码可以验证手机号的有效性,短信验证应用的地方越来越多,写这篇博文的原因是因为我司最近弄了个H5活动,有个发送短信验证码的功能由于java组没做防刷机制导致短信被刷。而他们的解决办法令我匪夷所思,因为根本起不到作用。所以想写一篇关于防刷的博文。

短信被刷也算网络攻击的一种,网络攻防一直是相爱相杀的存在。没有绝对的防御,只有不断增强防御,提高攻击者的攻击成本,使其攻击成本高于收益,从而放弃攻击。

短信防刷也是同样的道理,就是不断的增加攻击者的攻击成本。攻击者一般会尝试使用不同的攻击方式进行试探性攻击,根据反馈回来的信息做进一步分析,完善攻击方式,从而进行有效攻击。 所以对于明显属于攻击的行为,尽量不要给出明确的错误提示是非常重要的(业务逻辑错误的提示除外)。 这样,攻击者就不能很快的判断到底是什么地方验证没通过,从而增加攻击者攻击成本。

下面给出详细的放刷思路:

第一步,验证请求方式

一般网页发送验证码是通过ajax发送post请求,所以可验证是否是ajax请求、post请求。而APP、小程序等一般发送post请求接口,可验证是否是post请求。如果出现这类错误,基本是非法攻击行为,不要给出明确的错误提示,给出诸如“系统错误”之类的模糊提示。但,请求方式是可以伪造的,这种判断只能过滤小白攻击者,还需后续验证

第二步,分析请求头中的Referer

一般情况下,用户先进入页面输入手机号然后点击发送验证码,所以可以根据请求头中的Referer来分析用户是不是通过这个页面地址进入的。但,Referer也是可以伪造了,但对于低级攻击者,有可能没想起来伪造。 这类错误也不要给出明确的错误提示。

前两步可以防御一些简单攻击,如果不给明确的错误提示,攻击者可能要经过很多次不同的尝试才会发现,增加了攻击成本。

第三步,验证手机号

一般使用正则验证即可,这步主要是过滤无效的手机号。

第四步,验证该手机号当天发送了多少次验证码

规定每个手机号每天只能发送多少次验证码,这么做的目的是防止攻击者利用此功能对某个手机号短信轰炸。虽然一般短信通道会对此行为做限制,但还是根据自身的需求做下防护比较好。可以利用redis等高速缓存服务器存储每个手机号当天发送的短信数量。

还可以根据需求,限制验证码的发送频次。

第五步,验证该ip地址当天发送了多少次验证码

规定每个ip地址每天的发送量。不过需要注意几点:
1、同一局域网内用户对外访问的ip都是同一个,值设置的过小可能会影响正常的用户,需哦亦需要注意。
2、客户端的ip地址不要使用请求头中的X-FORWARDED-FOR,因为可以伪造,PHP中$_SERVER的HTTP_CLIENT_IP值也是不可信的,因为都可以伪造。
3、由于业务特点,有可能会造成误伤。所以最好能建立ip黑、白名单制度。通过日志或代码检测可疑的ip拉入黑名单中,对于误伤的ip加入白名单中。

以上五步基本可以防御绝大多数的攻击,但对于使用代理或者攻击者手上有大量的ip资源,还是会有被攻击的可能。

如果还被攻击,可以增加图片验证码机制。验证码机制可以放在第三步和第四步之间。但是图片验证码也是有可能被识别的,所以要根据攻击强弱增加验证码的复杂度。
包括不限于:
1、使用复杂的规则,比如输入计算结果、输入指定颜色的字符中文等等。
2、多个背景图随机使用。
3、多种字体随机使用。
4、字体适当倾斜、变形
5、增加长短、粗细、颜色不同的干扰线
6、增加干扰点
7、验证成功或失败自动切换验证码
。。。

这样的话基本可以防御99%的攻击,如果还被攻击,那还有最后一步:
求对面神仙放过。。。

你可能感兴趣的:(网络安全,php)