基于操作链的风险控制系统的设计与实现
2022-07-08刘龙锦张志杰梁世民
刘龙锦 张志杰 梁世民
(北海职业学院 广西壮族自治区北海市 536000)
在大数据时代,数据的重要性不言而喻,保护用户数据和信息安全是每一家互联网公司都应该重点布防的区域。知名的互联网公司的应用产品基本都会安装配置风险控制系统以保证自家数据不会被攻击者随意爬取,点赞评论播放量等敏感数据不会被攻击者随意刷量。传统的风险控制系统通过在Http请求的Header参数或者Url参数中嵌入加密字段或者字符串、为设备生成不同权重的设备号、校验IP地址、收集客户端的部分操作信息等方式来实现对请求的校验,如果服务器判定通过则返回正确数据,判定不通过则返回错误信息或者返回虚假的数据。
攻击者在破解了客户端与服务端的Http通讯协议后,风险控制系统就不能有效的阻止攻击者规律性的、频繁性、有目的性的请求接口操作。这类风险控制系统重点的实现部分在于客户端的发送到服务端的Http请求链接的加密签名上。具体的工作主要在客户端应用的代码层实现对应的加密算法,常见的加密算法有AES、MD5算法等。代码层面的主要防护手段则有代码混淆、应用加壳等方法。这些防守方式实现起来较为简单也较为成熟,也经过了时间的校验。而此类风险控制系统的风险控制效果主要取决于加密算法的强度和复杂度。由于客户端应用是运行在客户的设备上的,所以是无法避免客户端遭到破解的,也就是无法避免客户端的加密算法遭到破解,一旦攻击者破解了客户端的加密签名算法,配合多设备、多账号、代理IP等资源即可实现大规模的数据抓取和数据的刷量操作。为了解决这些问题,基于操作链的风险控制系统在传统风险控制系统的基础之上,通过判断用户请求数据的完整链路判定请求是否合法,是对传统风险控制系统的完善,两者相结合,进一步提供系统的安全性,降低数据被大量抓取的风险,保障用户数据安全。
1 系统设计思路
传统风险控制系统往往只是验证通信协议的完整性,并未考虑操作链路的完整性,在通讯协议遭到破解后,攻击者便可肆无忌惮的访问某个接口从而达到刷数据量或者批量抓取数据的目的。基于操作链的风险控制系统的设计思路从客户端的操作链路的完整性切入,在传统的风险控制系统之上加入对操作链路的验证功能,在传统的风险控制系统的验证点验证通过之后再重点验证客户端的操作链路是否完整,需要两个部分的验证点都通过验证后才会认定客户端的请求是合法有效的。
以小红书Android客户端首页推荐读取某篇笔记为例,客户端正常的请求链路应该为:
(1)读取首页推荐数据;
(2)点击进入笔记详情;
(3)读取笔记详情数据;
(4)读取笔记评论数据;
(5)用户阅读笔记详情;
(6)客户端发送阅读后操作。
小红书Android客户端与服务端通信加密字段主要是Shield字段,Shield字段的加密算法位于So层,使用了Aes加密算法和自行修改的Md5算法,具体的计算规则为:
(1)APP启动时从服务器获取到对应的XyTer数据用于加密(充当密钥功能)。
(2)获取客户端信息,生成出对应的DeviceId数据,版本数据等。
(3)请求某个Url链接时,将Url链接的Path路径,Params参数拆分作为参数。
(4)将XyTer数据、DeviceId数据、Path路径、Params参数、Common参数传入到So层计算得到Shield。
(5)将计算得到的Shield数据置入到Http请求的Header参数中发送给服务器。
由于Shield字段检验操作的权重在小红书的风险控制系统中的占比是比较大,攻击者在解密了Shield字段后,模拟发送对应的Http请求即可成功欺骗小红书的风险控制系统。因此攻击者对小红书进行攻击时,可以把操作链路简化为直接读取笔记详情,忽略前置的读取笔记列表和点击笔记操作与后置的读取笔记评论和阅读笔记操作。在研究小红书的Shield算法是,笔者使用的是最新版本的7.12版本,依然可以成功欺骗到小红书的风险控制系统,可见小红书的风险控制系统对此类攻击手段并未做过多防范,这导致了小红书读取用户数据、笔记详情、用户作品等数据是极其容易实现的,所以市面上有很多数据服务商可以提供小红书的数据抓取服务,这对小红书的用户数据安全以及小红书的软件发展是极其不利的。
攻击者在解密了小红书Shield算法之后,通过Fiddler抓包软件获取Http协议需要提交的数据,使用PostMan工具或者使用Java语言的OkHttp框架编写代码,模拟构建与客户端一致的Http请求并完成Shield字段的计算后置入到Http请求中,即可正常读取小红书笔记的详情数据,如图1所示。
图1:小红书笔记详情数据
从图1的代码中可以看到,攻击者并不需要完成前置和后置的验证操作即可得到小红书的笔记详情数据,从这一点可以证实在传统的风险控制系统中签名算法占据的权重是比较高的,大部分的风险控制系统验证完签名之后便认定此次请求有效合法,这一类风险控制系统,如果签名算法的加密强度足够强及应用层的防护做的足够好的话,确实是能够极大的提高应用被破解的难度,应用在生产环境中也可以抵挡住大部分攻击者的攻击。
安全是相对的,防护强度再高的系统也会存在漏洞,只要是运行在客户端的软件,都会存在被破解的风险。无论Android客户端还是IOS客户端的加密算法都是会被破解的,只是破解的时间问题而已,对于逆向经验丰富的攻击者而言,无论是代码混淆亦或者是进行加壳操作,都仅仅只能拖延住攻击者破解协议的速度而已,并不能完全保障应用不会被破解,而且Android系统是开源的系统,开发语言也使用开源的Java语言,编译所生成的APK安装包只需简单的反编译即可得到还原度较高的源代码,这对攻击者来说是及其方便的。
为了解决风险控制的此类问题,我们需要在传统的风险控制系统的基础之上,增加对客户端的操作链路的完整性的校验,确保通信协议在破解之后仍有一定的风险控制能力。而基于操作链的风险控制系统设计核心思路就是降低加密算法校验结果在风险控制系统的权重值,重点验证某次操作的前置后置操作是否完整,通过验证链路完整就可以有效的解决此类问题。以上述小红书读取笔记详情为例子,在使用基于操作链的风险控制系统后的验证步骤为:
(1)客户端发出读取笔记详情数据请求并带上合法签名数据,服务端接收客户端的数据并校验签名无误及客户端的环境参数正常无误。
(2)检查客户端是否有读取首页数据行为,未读取首页数据则立即返回错误信息,如果已读首页数据则进一步检查首页历史数据是否存在对应的笔记ID。
(3)如果首页的历史数据不存在该笔记ID则判定为此次请求为非法请求同时返回错误信息,如果历史数据中存在该笔记ID则返回该笔记ID的详细数据。
(4)风险控制系统延时1-2秒左右检查客户端是否有读取改笔记ID对应的评论数据及后置操作是否完整,如果客户端未执行后续的操作或者操作链路不完整则暂时将该客户端认定为一般风险设备,该客户端在执行下次请求时要求完成系统预先设计好的验证过程,一般是弹出验证滑块或者输入验证码等操作。
综上,在完成了对传统的风险控制系统的改造升级之后,由于加入了对客户端操作链路的校验,即使是客户端与服务端之间的通讯协议遭到破解,基于操作链路的风险控制系统依旧可以根据用户的操作链路和历史行为来判定用户的请求是否有效,最大程度的保障用户的数据安全以及系统的稳定运行。
2 系统实现方法
基于操作链的风险控制系统在实际的开发中,需要在传统的风险控制系统的基础之上,从数据存储,链路设计,链路判定三个方面出发,对传统的风险控制系统进行完善和升级,确保整个风险控制系统能够高效稳定运行,在进一步的提高风险控制的能力的同时,尽可能减少对正常客户端的误伤行为及对系统资源的合理调度使用,以下将从上述三个方面对风险控制系统的实现进行详细的说明:
2.1 数据存储
客户端的操作行为数据及请求接口时系统返回的数据需要使用数据库系统进行数据存储,由于此类数据较为复杂且不具备有统一性,在选择数据库系统时要充分考虑以下的业务场景:能存储不规范数据、增删查改的速度快,数据库性能足够强大、数据占据的存储容量足够小。传统的关系型数据库很难满足此类需求,使用基于内存技术亦可持久化存储并支持Key-Value键值对,并提供多种语言API的Redis数据库可以很好的解决数据存储的问题。在配合传统的数据库存储需要长期存放的数据,做好对应的数据容灾方案,确保数据库系统正常运行,保障用户数据的安全。
在风险控制系统确定最终选择的数据库系统之后,需要开发者建立对应的数据模型存储客户端操作行为数据以及客户端某次请求的系统返回的接口数据,此类数据大部分是Json数据,使用键值对存储具有先天的优势。除了建立数据模型之外,还需要建立对应的数据管理机制,将客户端对应的操作数据以及服务端响应给客户端的数据按照具体的业务需求进行存储,并定期定时删除已过期的数据,合理的控制数据量的大小,降低数据存储成本,尽可能减轻数据库系统的负担,尽力提高数据查询的速度。
以读取文章详细数据为例子,数据库系统将客户端在某个时间段内的操作记录、请求的接口信息、对应接口返回的Json数据存储在Redis数据库中,当用户发出读取文章详情数据时,在Redis数据库中查找对应的文章数据,再根据数据库查找返回的结果为风险控制系统的判定提供依据。
2.2 链路设计
链路设计对服务端与客户端的架构提出极高的要求,需要开发人员清楚掌握每一个业务的完整链路,确定好每一个业务的前置条件及后置条件,这是风险控制系统中最难设计及实现的一环。在开发的前期,就需要做好业务的链路规划,进行版本更新增加新功能时也需要评估新链路的加入对系统的影响。
并不是所有的功能都需要进行链路设计,在风险控制系统运行的前期,对部分安全性要求高,数据隐私敏感的接口进行链路设计即可,类似检查版本,读取公共配置等接口则不需要进行链路设计,类似点赞,评论,读取个人信息,读取实体信息等接口则需要做好对应的链路设计。在风险控制运行稳定之后,在逐步对其他的接口进行链路设计,确保风险控制系统的完整性。在实际的客户端应用开发中。
同样的功能可能会存在多条链路操作,例如获取某个文章详情时,用户可能是从首页进入,也有可能从收藏夹进入,或者从他人推荐页面进入,这就会造成部分功能具有部分相同操作链路的情况。对于部分重合的链路,可参考面向对象的编程思想的类设计模式进行设计,将他们尽可能的统一起来,减少对应的工作量,尽可能做最小的设计完成更多的功能。
除了常规的链路,客户端中或多或少还存在一些特殊的链路,对于特殊链路的设计也要今早的做好准备方案。例如Android客户端常见的通知栏功能,允许用户从系统的通知栏中直接点击对应通知跳到对应的Activity界面,此类业务场景也应该做好对应的链路设计,确保客户端稳定运行,不会因为链路的特殊性导致风险控制系统误判而影响用户的正常操作。
2.3 链路判定
链路判定是基于链路操作的风险控制系统中最为重要的一环,链路判定的准确性影响着风险控制系统性能指标,服务器资源消耗大小,客户端使用体验等。通常来说攻击者对风险控制系统的攻击大部分为对某个接口进行破解后通过大量的账号数据、代理IP数据执行单一的请求,从而达到刷量、刷数据、抓取数据等目的。大部分的攻击者不具备有某个接口的完整操作链路信息。链路判定的主要工作量在服务端,判定的主要工作是对客户端发起的请求完成链路判定并确认是否合法。
以评论文章功能为例,客户端发出请求评论文章请求并携带文章ID及评论内容到达服务器之后,基于操作链的风险控制系统第一步从数据库中读取历史数据,先判定客户端是否有读取文章详情的操作。如果客户端没有读取文章详情的操作就对某个文章进行了发表评论,很明显就是属于非法请求,风险控制系统应当立即判定此次请求无效,返回错误数据或者假数据。如果历史数据中对应的证据支持用户读取了文章详情,则往上回溯一步,继续判定用户是否有读取文章列表操作,如果没有读取文章列表操作,则判定本次请求依旧无效。如果判定客户端有读取文章列表的操作,则还需要在判定服务端返回的数据中有无该文章ID,如果没有文章ID,则判定本次请求依旧无效,显然在读取文章列表是并没有返回此文章ID,如果客户端又去读取了此文章ID的详情,则可以判定为攻击非法构建的请求。风险控制系统在完成上述的前置判定后,如果判定了请求有效则后续要执行完整链路的后置判定操作,如果客户端未执行后续的链路操作则判定为一般风险行为,客户端弹出相应的验证界面验证是否真的是用户在操作客户端,在用户完成验证之前,风险控制系统应该将此客户端列为风险客户端,对风险客户端发送的请求一律拒绝直至完成校验操作才可继续提供服务。
由于目前技术水平的限制及服务器的计算资源的有限性以及系统对响应时间的要求,验证某个请求的完整链路会消耗较多的计算资源,造成客户端获取服务端的数据过慢,也就是服务端的响应时间边长,从而影响用户的使用体验。一般对客户端的请求判断三步以内链路规则即可确认该请求是否有效。对于会影响到数据量的接口和部分较为重要隐私的接口,需要根据实际的业务需求加大链路判定的步骤数量,在这方面不应该考虑计算性能的问题,应该把保障安全放在第一位。在链路判定方面,尽可能的做到风险控制效果与服务器计算资源之间的平衡。在链路校验算法设计方面,应该尽可能提高算法的效率,不断的优化算法的准确性,必要时采用AI辅助计算,通过软硬件的优化,持续提升链路判定的效率及准确性。
3 系统测试
在完成基于操作链的风险控制系统的设计与实现之后,在上线到正式环境之前,需要按照预期的风险控制目标,对风险控制系统展开系列测试,通过对系统的测试,掌握了解基于操作链的风险控制系统可能存在的BUG隐患,并有针对性的修复功能,确保风险控制系统的稳定性及风险控制能力达到预期设计水平。
系统测试主要集中在数据存储,链路验证,风险控制能力几个方面,在测试的同时要关注服务器计算资源的消耗、数据存储大小增长比、风险控制系统对风险请求的拦截能力、风险控制系统对正常用户的误伤几率。
以读取文章详情测试为例,通过观察客户端的正常请求是否能够返回正确的数据,可使用PostMan等Http网络测试工具模拟攻击请求观察风控系统是否能够正常拦截非法请求。在测试的时候需要进行多次测试,模拟攻击者会使用的攻击方式,从单个步骤到多个步骤的链路都需要精选测试。根据最终的测试效果,进行相对应的参数调整及BUG修复,确保风险控制系统高效稳定的运行。
4 结语
基于操作链的风险控制系统的设计与实现并不是一套独立的风险控制系统,它是对传统的风险控制系统的完善和升级,是建立在传统风险控制系统之上的,是传统风险控制系统在通信协议遭到破解之后较为有效的一种解决方案。基于操作链的风险控制系统目前主要的问题是对数据存储、服务器性能及软件架构伴以及操作链路的链路验证算法等几个方面要求较高,这也是比较明显的缺点。但是随着服务器的计算性能的提升及校验算法的改进还有存储市场的蓬勃发展,基于操作链的风险控制系统会逐步解决这些问题,在未来会在风险控制领域成为一种可靠的、可行性高的风险控制技术方案。