对于每一个客户的问题,不管大小,都需要跟进追踪到底,以获得最佳的答案。

一个问题一个坑,留了坑,前路必将荆棘丛生;填了坑,前路即是坦途。这是东门人的做事态度和行事准则,也帮助我树立了积极的人生观。

如果同行也正在经受类似问题的困扰,希望同行可以通过这篇文章,在排查过程中能够获得一点启发。

刷量?客户反馈异常 IP 发送大量重复数据

从今年 2 月份起,我陆续收到客户反馈:Web JS SDK 短时间内上报了大量重复的数据到银联商务,从而影响了客户的分析、决策和制定运营计划。对于这种情况我们通常称之为 “刷量”。什么是刷量?

图 1 刷量表现—按天

图 2 刷量表现—按分钟

用户所反馈的现象和刷量一致,有几个异常 IP 短时间内密集发送 Web 端重复数据入库。一个 IP 一天发送的重复数据甚至达到了几十万、上百万条,这显然不是一个正常用户产生的行为数据。

我们查看了刷量时的用户行为序列,如下图,可以看到事件是重复循环触发的,时间间隔在几十毫秒。

图 3 刷量发生时的用户行为序列

针对此问题的反馈,我们进行了快速排查及提供初步行业资讯。 当时的排查思路:

一,会不会是客户代码 bug 导致重复触发事件?

通过协调运维帮忙查询事件日志,证明这些重复事件的 trackid(Web JS SDK 对发送数据生成的随机数,每条采集和发送的数据都会有自己独特的 trackid) 是一样的。从这个方面看,基本排除了是客户代码 bug 导致的,因为即使是代码重复触发的事件,trackid 是不会重复的。

二,会不会是别人恶意获取了东门的大嘉购APP请求和数据体,使用工具或者脚本伪造请求,灌注脏数据到银联商务服务器?

Web JS SDK 采集的数据,默认使用 image 方式发送数据,GET 请求的数据接收地址和数据体都包含在请求的 URL 中,如图所示:

图 4 Web JS SDK 的数据发送

只要复制该 Request URL 直接在浏览器地址栏访问,或者使用脚本访问,就会有一条一模一样的数据入库。这也符合 trackid 重复的情况,而且可以集中产生大量的请求,实现灌注脏数据。在本地使用脚本模拟,也能够复现出来数据刷量的情况。

因此,推测的结论是:有人从集成了 Web JS SDK 的页面上,截取了发送的数据请求,并通过脚本灌注脏数据进入银联商务。

根据这一结论,给客户的方案是:将 Web JS SDK 的数据发送方式从 image 改成 ajax,这样请求就会从 GET 变成 POST,在一定程度上避免将整个请求暴露在 URL 上;将出现过刷量的 IP 增加到后端的防火墙黑名单中。

问题又现!存疑,再深入排查

但是,似乎并没有解决问题。在接下来的一个月,依旧陆续收到刷量的情况反馈。

我每天值班也都胆战心惊,只要有客户反馈刷量的情况,心里都咯噔一下:如果是有人恶意刷量,那么持续刷的动作有点说不通,是否有其他原因导致……问号一直悬在那里,始终无法说服自己。

我们内部组织 Web JS SDK 开发人员来集中开会讨论,当时判断刷量的可能原因:Web JS SDK 的 bug 导致?有人恶意攻击,灌注的脏数据导致?后端服务中的 bug 导致的重复读取数据导致?

为了验证我们的推测,申请了一个客户被刷量的环境查看,判断不是 Web JS SDK 和后端服务的 bug ,目前的方向也只剩下是有人恶意攻击了。Web JS SDK 在前端针对这种情况,没有什么方法阻止,寄希望于后端可以将这样的刷量数据去重。

由于 Web 端的数据入库后,默认使用服务器时间,而服务端的去重逻辑是根据 trackid、time 等一起去重。像这样的刷量数据入库,虽然 trackid 一致,但是 time 相差只有几十毫秒,因此无法去重。为了解决这一问题,可以在后端对于 Web 端数据的去重逻辑中将 time 字段去除,这样就可以对刷量数据进行去重了。

不过,这只是一个临时行业资讯,且该方案只针对集群版有效,有一定的局限性。另外,这种方案属于出现了刷量后的被动处理。

“用力啊!”

对于此问题,书记也一直怀疑,每天见我必问:“有进展吗?用力啊!” 由于并没有找到确定的原因,我在网上查到 image 请求死循环的资料,如下图所示:

图 5 image 请求死循环资料

于是我查看 Web JS SDK 源码,发现已经对 image 请求的 onerror 做了 null 赋值处理,不会出现死循环现象。有点失落,这个方向也是不对的。

场景难以复现,多次转机出现却屡陷僵局

终于,转折出现了。当我与被刷量客户的技术做深入沟通时,有了一个重大发现。

4 月的某天,客户拿到注册用户的手机号,通过技术人员联系到这个用户。发现用户是正常操作,只是使用了某浏览器访问页面。当时,远程客户电脑进行操作,发现如果关闭浏览器后就会停止刷数据,浏览器处于开启状态就会一直刷数据。另外,发现用户的浏览器版本比较老,让其升级到最新的浏览器后,依然能够出现刷数据的情况。同时,在访问页面时页面会有卡顿情况,风扇也转的特别厉害。另外,同一时刻该用户对客户自己页面的一个水印图片访问量也很大,达到了 21.4 万次。但是,对东门的 sa.gif 访问量更多,达到 255.4 万次。

不过当客户的技术在自己电脑上模拟的时候,无法复现这个问题。查看当前稳定版的 M 浏览器内核为 Chrome 78.0.3904.108。通过这个发现,我去查看其他客户的最近刷量数据,均发现其 UA 是 Chrome 78.0.3904.108, 指向 M 浏览器。通过以上线索推论:刷量问题很可能不是人为恶意攻击,而是 M 浏览器访问针对 image 数据请求可能有无限循环的 bug 导致的。

按照客户提供的线索,我反向查看了下:以该内核版本为筛选条件,发现出现刷量的那天,有近 5300 个用户使用该内核版本访问了页面,而出现刷量的情况只有 1~2 个用户。从这方面看,刷量似乎不是必现的。本地使用多台电脑,测试 M 浏览器均没有能够复现,问题似乎又陷入了僵局。

再换一条路,基于 M 浏览器的问题判断,我当天我在浏览器社区留言,希望可以从浏览器的工作人员那里可以获得答复和帮助,如图所示。

图 6 留贴浏览器社区

工作人员通过 QQ 联系了我,并与我沟通了基本情况。由于他们没有受理过类似问题,希望我提供复现的页面,但是我这边没有复现的页面。因此,这个方向的路也堵住了。

感恩信任!与「客户的用户」的多次远程、面基……

在走投无路时,几经辗转,为复现场景,我再次联系客户的技术人员,希望能够联系到之前两位用户。经过客户的提前沟通,以及一系列的保密协议签署后,最终提供两位用户的联系方式。

起初我几次联系,都没有能够打通电话。而此时,刷量问题愈演愈烈。因为线索只剩下这一条了,我就硬着头皮继续打电话,终于还是拨通了。

在此很感激两位用户的信任。第一位用户帮忙安装了 TeamViewer,并提供了远程。可惜的是这一次没有复现刷量的情况。

不能匪⒖