在这里分享一些以前对某网站会员/用户系统(通常域名都是passport.xx.com)进行漏洞检查查出的一些问题,这些问题大多都是逻辑类漏洞,利用漏洞进行攻击并不须要什么高深的技术能力,因此危害尤为大,把相关经验分享给你们但愿你们能够自查。前端
这里要说明,下面不少漏洞的例子是基于已经得到有效的帐号密码(行话说就是密正的帐号)的前提的,你们可能会问:程序员
一、怎么可能拿到别人的帐号和密码?其实有不少网站都泄露过带明文密码的帐号库(也有一些帐号库是不带密码的,或者是MD5哈希后的密码,不带密码的能够用一些常见简单密码尝试,MD5后的密码能够用云MD5密码库来“解密”),不少人会用一些工具拿手头拿到的几百万个帐号密码针对某网站进行逐一的登陆测试(这个过程叫作扫号),遇到有验证码的网站使用程序自动识别密码,更高级一点可使用云打码平台来识别验证码,只要能登陆那么这个帐号密码就是针对这个网站的密正帐号,就能够以必定的价格卖给收号的人了(好比5元一个帐号),扫号的人干的是纯技术活,至于收号的人拿到帐号去干啥这就根据网站不一样各不相同了(对于游戏网站的帐号拿去后基本是洗号之类的)。ajax
二、既然已经拿到了帐号和密码什么均可以干了,还谈什么漏洞?不少网站虽然有帐号密码能够登陆,可是一些关键性操做每每有双重验证的(好比经过邮箱验证,经过手机验证),更况且有一些网站有帐户安全策略,若是检测到帐户不安全的话(好比是异地登陆)可能会须要经过手机验证码验证后才能登陆。因此通常状况下即便有别人的帐号你也只能登陆到他的后台看看,几乎不可能作什么敏感操做(好比提取帐户余额、修改密码之类的),只有进一步把一些绑定换绑以后才可能有进一步的行为。浏览器
假设本身的帐号是A而且已经绑定过邮箱,手头密正的帐号是B。安全
一、使用A帐号登录网站,在浏览器中开两个页签。工具
二、进入更换邮箱的功能,页面会提示须要获取验证码,点击获取后进入了“更换邮箱”界面,在这个界面中网站会要求你输入验证码以及但愿更换的新邮箱。测试
三、刚才不是打开了两个标签页面吗,到第二个标签页面点击登出,使用B的帐号登录进入网站后一样进入更换邮箱的功能,点击获取验证码按钮。网站
四、 在第一个页签更换邮箱的第二步输入一个新的要更换的邮箱xx,而后输入正确的验证码(到A帐号绑定的邮箱查看验证码)完成更换邮箱的流程(其实当前登录的帐户已经是B)。加密
五、在第二个页签刷新一下页面,能够看到B的邮箱已经更换为xx。spa
也就是说更换邮箱这个操做的第二步直接读取了B的登录信息进行了更换,而没有验证B已经不是当初提出更换邮箱申请的A了,没有把操做做为总体验证致使漏洞的发生。若是网站有这个逻辑漏洞,那么极可能更换手机功能也能够这么破。
若是玩游戏可能知道有一种叫作密保卡的东西,好比是一个X*Y(好比10*10)的二维表格,每一格都是一个数字,玩家在作敏感操做的时候须要输入密保卡上指定位子的三个数字,所有输入正确后才能够进行操做。好比会要求你输入(A10,C2,F8)三个坐标的数字,你须要查看密保卡找到这三个数字依次输入,若是你没有密保卡,密保卡的数字范围是0-99那么每个数字猜中的几率就已是1%了,三个数字所有猜中的几率是百万分之一(左右),因此是一种简单且基本有效的安全验证方式。
如今AJAX技术用的不少,若是对于密保卡验证的操做也采用了一个相似checkmibao/?locations=A10,C2,F8&code=11,22,33这样的AJAX请求当然能够达到功能需求,可是有没有想过,这种API(若是没有请求频度限制)很是容易快速爆破,彻底能够模拟这样的请求checkmibao/?locations=A1,A1,A1&code={0},{0},{0},参数{0}来一个循环从0到99(最坏的状况是尝试100次,这里要说明的是既然是爆破这里提供的三个坐标确定是相同的坐标位置),若是返回的结果是正确的则A1的密保已经得出了,不然继续查询,对于表格的其它坐标A2-J10也一样进行一样的操做很快就能够把整个密保卡“计算”出来(若是不是那么贪婪的话能够拿到坐标后直接计算3个坐标,会快一点)。应该怎么改?API彻底不该该设locations参数,由于用户在验证密保卡的时候系统是知道验证的三个坐标的,仅仅是checkmibao/?code=11,22,33这样就能够了。
其实说白了这个漏洞出现的缘由是没有遵循“客户端的一切是不可信”的原则,只能相信服务端的数据,客户端提交的数据始终要带着怀疑的态度来处理,任何数据只能做为参考或呈现不能做为参数直接使用。除了这个问题以外,AJAX也可能会带来一些安全隐患,这种隐患和AJAX并没有关系,而是不少开发人员在作AJAX接口的时候会错误的以API的心态去开发而忘记了接口是网站的一部分,好比:
一、 有的时候为了屏蔽一些数据的呈现(好比IP地址显示为192.168.*.*),只是在前端进行数据格式化,AJAX接口仍是提供了原始数据192.168.0.1那么彻底达不到安全的目的。
二、 AJAX接口每每轻量,刷起来也快,并且容易遗漏对访问频度的控制,更容易爆破。
三、 无刷新意味页面的初始加载和后续操做的验证会分段,分段就容易产生漏洞。
如今不少网站都会制做APP版本,在测试此网站的APP后发现和服务端的交互参数都进行了签名+BASE64,咱们知道安卓的应用程序是能够反编译的,通过反编译能够查看到:
一、公钥私钥都写在了Java代码里,使用公钥来加密要发送给服务端的数据,使用私钥来解密从服务端返回的数据,这样就能够经过翻译服务端返回的数据来熟悉API也能够绕过客户端直接发送请求给服务端。
二、了解了全部API后发现代码里有一个隐藏API没有用到,通过测试这是一个“内部使用”的API,能够经过这个API把某个客户端换绑到帐户而且无需进行其它验证。至此整个网站的帐号安全都由于这个点失守了。
这个过程看上去很简单,但要发现这个漏洞是通过了大量的尝试的,要先熟悉整个操做流程,逐个尝试是否有逻辑漏洞和其它突破点,每个漏洞都是不一样的不是每个APP都会有隐藏的内部API,每一次可能的突破每每都是基于很是规思惟。
那么改进方法也很简单,把KEY值以打散方式存储于SO文件中,最好协议的加密解密全采用C编写,在Java层对于协议都是透明的。
可别小看这几个漏洞,出现这样的漏洞意味着黑客能够随便修改用户的邮箱、手机、密码、从而绕过各类二次验证,把帐号彻底掌握在本身手里。若是扫号的人手头有1000万个帐号库,扫到密正帐号50万个,想一想也吓人。从这几点我以为能够总结一下,对于网站的安全始终要记住几点:
一、木桶理论,整个网站99%的地方都很安全是不够的,若是网站的帐户体系是打通的,那么只要有1%的地方有问题,其它99%的安全都是白搭,找漏洞的人每每也最喜欢找(由初级程序员开发的)边缘模块下手。
二、不要信任客户端的任何数据,对于每一项由客户端提交的数据咱们都应该当作是用户的输入(哪怕这个数据原本就是从服务端读取的),进行严格的验证。
三、对于已经实现的逻辑要思考一下是否是有很是规的路径,是否有能够绕过的逻辑。
四、作好请求的频度监控以及控制,若是发现某些请求访问量徒增可能就会是一个漏洞点在被别人爆破。
五、重要的功能尽可能不要去走AJAX,不是说AJAX有什么问题,而是AJAX容易让人放松警戒。若是能够的话让(AJAX)请求或API调用变得彻底没有意义,好比使用统一的通用的AJAX API提供接口,好比http://passport.xxx.com/ajax?token=xxx,token是在服务端事先生成的对应了某个操做逻辑,使用后则失效,即便是相同的API token也是动态的(而不是为每个业务分配一个具体的URL,这样只根据token根本就不知道是哪一个业务,若是别人不能熟悉你的流程固然也很难去破解逻辑漏洞)
六、不苛求用户有很强的安全意识,做为网站的开发要主动保护用户的密码等敏感信息,提示用户常常修改密码,并为网站创建安全分析体系,对用户的操做进行安全评级,若有必要对用户的登陆请求进行驳回。