11.1 验证码
验证码可以解决很多业务安全问题,比如撞库、垃圾注册,等等,可谓防御业务风险必备神器。验证码有图片验证码、滑动验证码、短信/邮箱/电话、二维码等分类,而据保守估计起码有80%以上的验证码是存在可以爆破和简单识别的问题,设计一个有效的验证码尤为重要。
11.1.1 验证码绕过
图片验证码是目前见得比较多的,各种各样的图片验证码形式也比较多和奇葩,有中文、英文、字母数字和看图识物,等等,简单列举一下,如图11-1~图11-3所示。
图 11-1
图 11-2
图 11-3
不得不吐槽一下,一些验证码为了避免机器识别,已经被逼得设计成人类都认不出来了,业务和体验设计与安全是有一点矛与盾的,所以从业务角度考虑,我们还是能找到很多绕过这些验证码的方法,我们来一起看看。
1.不刷新直接绕过
Web页面登录等操作的验证码能够多次使用的原因是后端程序在接收一次请求后,并没有主动刷新验证码,部分比较大的业务使用了负载均衡,验证码跟Session绑定在一起,为了能够保证验证码能够正常使用,所以会把验证码明文或者加密后放在Cookie或者POST数据包里面,所以每次只要同一个数据包里面的两个验证码对上了即可绕过。
2.暴力破解
注册或者找回密码等敏感操作时的手机或者邮箱验证码能够爆破,主要是因为程序没有设置验证码错误次数和超时,导致能够不断进行尝试。
3.机器识别
机器识别验证码对于不同的验证码类型有不同的手段,最常见的是图片验证码的机器识别,这类识别有两种情况:一种是针对不是实时生成的验证码,已经生成了部分的验证码在服务器端保存,前端直接加载验证。这类是最好绕过的,只要把全部的验证码文件保存回来,做一个图片MD5库,然后利用的时候直接匹配服务器端返回的图片MD5即可识别。另外一种是动态生成的验证码,这类需要做一些图片文字识别或者语音识别,当初有一个笑话讲的是Google出的语音识别系统干掉了自家的语言验证码。国内也有专门提供这种服务的公司,比如云速,如图11-4所示。
4.打码平台
这类打码平台大多数后端是使用廉价的人工资源在打,比如学生什么的,国内比较有名的像打码兔(damatu1.com)、Q赚(qqearn.com),等等,让我们来看一个任务佣金表就知道成本有多低,如图11-5所示。
经过上面的分析,我们大致可以知道怎样设计一个强壮的验证码,主要有以下几点:
1)最重要的是,要设置验证码错误次数,比如一个验证码只能错误一次,这就避免了暴力破解的问题。
2)不把验证码放到HTML页面或者Cookie中。
3)验证码要设置只能请求一次,请求一次后不管错误与否都在后端程序强制刷新。
图 11-4
图 11-5
4)短信或者邮件验证码必须要6位以上字母和数字混合,图片或者语音验证码需要加强混淆干扰,比如图片文字变形,增加干扰斑点等。语音验证码增加背景噪声。
5)验证码要动态生成,不能统一生成多次调用。
11.1.2 验证码资源滥用
除了验证码识别外,验证码还存在一个大问题就是资源滥用。相信大家应该对短信轰炸或者邮箱轰炸比较了解,被轰炸的手机号会在短时间内收到大量短信,从而造成受害者手机一直响,也无法愉快地看短信,工具如图11-6所示。
图 11-6
我们来看看短信轰炸的效果,如图11-7所示。
图 11-7
从这些短信内容里面可以看到,这类工具是利用了大量网站的短信验证码接口,而这些接口没有限制获取验证码次数和时间间隔,导致了可以不断被调用,防护起来比较简单,只要注意限制单个手机号在一个时间段内请求接收短信的次数,另外就是限制某个IP在一个时间段内请求接收短信的次数,这是为了防止提交大量手机号,消耗短信资源。