活动 Web 页面人机识别验证的探究与实践
在电商行业,线上的营销活动特别多。在移动互联网时代,一般为了活动的快速上线和内容的即时升级,大部分的业务场景依然通过 Web 页面来承载。但因为 Web 页面天生“环境透明”,相较于移动用户端页面在安全性上存在更大的挑战。本文主要以手机端 Web 页面为基础来讲述如何提升页面安全性。
活动 Web 页面的安全挑战
对于营销活动类的 Web 页面,领券、领红包、抽奖等活动方式很常见。此类活动对于普通客户来说大多数时候就是“拼手气”,而对于非正常客户来说,可以通过直接刷活动 API 接口的“作弊”方式来提升“手气”。这样的话,对普通客户来说,就变得很不公平。
对于活动经营的主办方来说,假如风控措施做的不好,这类刷接口的“拼手气”方式可能会对企业造成较大的损失。如原本计划按 7 天发放的红包,在上线 1 天就被刷光了,活动的营销成本就会被意外提升。主办方想发放给客户的满减券、红包,却大部分被黄牛使用自动脚本刷走,而真正想参加活动的用,却无法享受活动优惠。
终端客户究竟是人还是机器,网络请求能否为真实客户发起,能否存在安全漏洞并且已被“羊毛党”恶意利用等等,这些都是经营主办方要担心的问题。
安全防范的基本流程
为了提升活动 Web 页面的安全性,通常会引入专业的风控服务。引入风控服务后,安全防护的流程大致如图所示。

Web 前台:客户通过 Web 页面来参加活动,同时 Web 前台也会收集用于人机识别验证的客户交互行为数据。因为不同终端(手机端 H5 页面和 PC 端页面)交互形式不同,收集客户交互行为数据的侧重点也会有所不同。
风控服务:一般大公司都会有专业的风控团队来提供风控服务,在美团内部有智能反爬系统来基于地理位置、IP地址等大数据来提供频次限制、黑白名单限制等常规的基础风控阻拦服务。甚至还有依托于海量的全业务场景的客户大数据,使用贝叶斯模型、神经网络等来构建专业度较深的服务。风控服务可以为 Web 前台提供通用的独立验证 SDK:验证码、滑块验证等区分人机的“图灵验证”,也可以为服务端提供 Web API 接口的验证等。
后台业务服务:负责解决活动业务逻辑,如给客户发券、发红包,解决客户抽奖等。请求需要经过风控服务的验证,确保其安全性,而后再来解决实际业务逻辑,通常,在解决完实际业务逻辑时,还会有针对业务本身的风控防范。
对于活动 Web 页面来说,加入的风控服务主要为了做人机识别验证。在人机识别验证的专业领域上,我们可以先看看业界巨头 Google 是怎样做的。
Google 如何解决人机验证
Google 使用的人机验证服务是著名的 reCAPTCHA(Completely Automated Public Turing Test To Tell Computers and Humans Apart,区分人机的全自动图灵测试系统),也是应用最广的验证码系统。早年的 reCAPTCHA 验证码是这样的:

如今的 reCAPTCHA 已经不再需要人工输入难以识别的字符,它会检测客户的终端环境,追踪客户的鼠标轨迹,只要客户点击“我不是机器人”就能进行人机验证(reCAPTCHA骗客户进行数据标注而进行AI训练的验证另说)。

reCAPTCHA 的验证方式从早先的输入字符到现在的轻点按钮,在客户体验上,有了较大的提升。
而在活动场景中引入人机识别验证,假如只是简单粗暴地添加验证码,或者者只是像 reCAPTCHA 那样添加点击“我不是机器人”的验证,都会牺牲客户体验,降低客户参与活动的积极性。
Google 的普通 Web 页面的浏览和有强交互的活动 Web 页面虽是不同的业务场景,但对于活动 Web 页面来说,强交互刚好为人机识别验证提供了客户交互行为数据收集的契机。
人机识别验证的技术挑战
理想的方案是在客户无感知的情况下做人机识别验证,这样既确保了安全又对客户体验无损伤。
从实际的业务场景出发再结合 Web 本身的环境,假如想实现理想的方案,可能会面临如下的技术挑战:
(1)需要根据客户的使用场景来定制人机识别验证的算法:Web 前台负责收集、上报客户交互行为数据,风控服务端校验上报的数据能否符合正常的客户行为逻辑。
(2)确保 Web 前台和风控服务端之间通信和数据传输的安全性。
(3)确保上述两大挑战中提到的逻辑和算法不会被代码反编译来破解。
在上述的三个挑战中,(1)已经实现了人机识别验证的功能,而(2)和(3)都是为了确保人机识别验证不被破解而做的安全防范。接下来,本文会分别针对这三个技术挑战来说明如何设计技术方案。
挑战一:根据客户使用场景来定制人机识别验证算法
先来分析一下客户的使用场景,正常客户参加活动的步骤是客户进入活动页面后,会有短暂的停留,而后点击按钮参加活动。这里所说的“参加活动”,最终都会在活动页面发起一个接口的请求。假如是非正常客户,可以直接跳过以上的实际动作而去直接请求参加活动的接口。
那么区别于正常客户和非正常客户就是那些被跳过的动作,对实际动作进一步归纳如下:
进入页面。
短暂的停留。
滚动页面。
点击按钮。
以上的动作又可以分为必须的操作和可选的操作。对这一连串动作产生的日志数据进行收集,在请求参加活动的接口时,将这些数据提交至后台,验证其合法性。这就是一个简单的人机识别验证。
在验证动作的合法性时,需要考虑到这些动作数据是不是能被轻易模拟。另外,动作的发生应该有一条时间线,可以给每个动作都添加一个时间戳,比方点击按钮一定是在进入页面之后发生的。
少量特定的动作的日志数据也会有正当的区间,进入页面的动作假如以 JS 资源加载的时间为基准,那么加载时间可能大于 100 毫秒,小于 5 秒。而对于手机端的按钮点击,点击时记录的坐标值也会有对应的正当区间,这些正当的区间会根据实际的环境和情况来进行设置。
除此之外,设施环境的数据也可以进行收集,包括客户参加活动时使用的终端类型、浏览器的类型、浏览器能否为用户端的容器等,假如使用了用户端,用户端能否会携带特殊的标识等。
最后,还可以收集少量“无效”的数据,这些数据用于障人耳目,验证算法会将其忽略。虽然收集数据的动作是透明的,但是验证数据合法性不是透明的,攻击者无法知道,验证的算法中怎样区分哪些是有效、哪些是无效。这已经有点“蜜罐数据”的意思了。
挑战二:确保通信的安全性
收集的敏感数据要发送给风控服务端,进而确保通信过程的安全。
Web API 接口不能被中途阻拦和篡改,通信协议使用 HTTPS 是最基本的要求;同时还要让服务端生成唯一的 Token,在通信过程中都要携带该 Token。
接口携带的敏感数据不能是明文的,敏感数据要进行加密,这样攻击者无法通过网络抓包来详细理解敏感数据的内容。
Token 的设计
Token 是一个简短的字符串,主要为了确保通信的安全。客户进入活动 Web 页面后,请求参加活动的接口之前,会从服务端获取 Token。该 Token 的生成算法要确保 Token 的唯一性,通过接口或者 Cookie 传递给前台,而后,前台在真正请求参加活动的接口时需要带上该 Token,风控服务端需要验证 Token 的合法性。也就是说,Token 由服务端生成,传给前台,前台再原封不动的回传给服务端。一旦加入了 Token 的步骤,攻击者就不能直接去请求参加活动的接口了。
Token 由风控服务端基于客户的身份,根据肯定的算法来生成,无法伪造,为了提升安全等级,Token 需要具备时效性,比方 10 分钟。可以使用 Redis 这类缓存服务来存储 Token,使用客户身份标识和 Token 建立 KV 映射表,并设置过期时间为 10 分钟。
尽管前台在 Cookie 中可以获取到 Token,但是前台不能对 Token 做持久化的缓存。一旦在 Cookie 中获取到了 Token,那么前台可以立即从 Cookie 中删除该 Token,这样能尽量确保 Token 的安全性和时效性。Token 存储在 Redis 中,也不会由于客户在参加活动时频繁的切换页面请求,而对服务造成太大的压力。
另外,Token 还可以有更多的用处:
标识参加活动客户的有效性。
敏感数据对称加密时生成动态密钥。
API 接口的数字签名。
敏感数据加密
通信时,传递的敏感数据可以使用常见的对称加密算法进行加密。
为了提升加密的安全等级,加密时的密钥可以动态生成,前台和风控服务端商定好动态密钥的生成规则就可。加密的算法和密钥也要确保不被暴露。
通过对敏感数据加密,攻击者在不理解敏感数据内容的前提下就更别提模拟构造请求内容了。
挑战三:化解纸老虎的尴尬
有经验的 Web 开发者看到这里,可能已经开始质疑了:在透明的前台环境中折腾安全不是白折腾吗?这就好比费了很大的劲却只是造了一个“纸老虎”,质疑是有道理的,但是且慢,通过少量安全机制的增强是可以让“纸老虎”尽可能的逼真。
本文一再提及的 Web 环境的透明性,是由于在实际的生产环境中的问题:前台的代码在压缩后,通过使用浏览器自带的格式化工具和断点工具,依然具有肯定的可读性,花点时间依然可以了解代码的逻辑,这就给攻击者提供了大好的代码反编译机会。
假如要化解“纸老虎”的尴尬,就要对前台的代码进行混淆。
前台代码混淆
前台的 JS 代码压缩工具基本都是对变量、函数名称等进行缩短,压缩对于混淆的作用是比较弱。除了对代码进行压缩,还需要进行专门的混淆。
对代码进行混淆可以降低可读性,混淆工具备条件的话最好自研,开源的工具要慎用。或者者基于 Uglify.js 来自己设置混淆的规则,混淆程度越高可读性就越低。
代码混淆也需要把握一个度,太复杂的混淆可能会让代码无法运行,也有可能会影响本身的执行效率。同时还需要兼顾混淆后的代码体积,混淆前后的体积不能有太大的差距,正当的混淆程度很重要。

断点工具的防范会更麻烦些。在使用断点工具时通常都会导致代码推迟执行,而正常的业务逻辑都会立即执行,这是一个可以利用的点,可以考虑在代码执行间隔上来防范断点工具。
通过代码混淆和对代码进行特殊的解决,可以让格式化工具和断点工具变得没有用武之地。唯一有些小遗憾,就是解决后的代码也不能正常使用 Source Map 的功能了。
有了代码混淆,反编译的成本会非常高,这样“纸老虎”已经变得很逼真了。
技术方案设计
在讲解完如何处理关键的技术挑战后,即可以把相应的方案串起来,而后设计成一套可以实施的技术方案了。相对理想的技术方案架构图如下:

下面会按步骤来讲解技术方案的解决流程:
Step 0 基础风控阻拦
基础风控阻拦是上面提到的频次、名单等的阻拦限制,在 Nginx 层就能直接实施阻拦。假如发现是恶意请求,直接将请求过滤返回 403,这是初步的阻拦,客户在请求 Web 页面的时候就开始起作用了。
Step 1 风控服务端生成 Token 后传给前台
Step 0 可能还没进入到活动 Web 页面,进入活动 Web 页面后才真正开始人机识别验证的流程,前台会先开始获取 Token。
Step 2 前台生成敏感数据
敏感数据应包含客户交互行为数据、设施环境数据、活动业务逻辑数据以及无效数据。
Step 3 使用 HTTPS 的签名接口发送数据
Token 可以作为 Authorization 的值增加到 Header 中,数据接口的签名可以有效防止 CSRF 的攻击。
Step 4 数据接口的校验
风控服务端收到请求后,会先验证数据接口签名中的 Token 能否有效。验证完 Token,才会对敏感数据进行解密。数据解密成功,再进一步对人机识别的数据合法性进行校验。
Step 5 业务逻辑的解决
前面的步骤为了做人机识别验证,这些验证不涉及到业务逻辑。在所有这些验证都通过后,后台业务服务才会开始解决实际的活动业务逻辑。解决完活动业务逻辑,最终才会返回客户参加活动的结果。
总结
为了提升活动 Web 页面的安全性,使用了各种各样的技术方案,我们将这些技术方案组合起来才能发挥安全防范的作用,假如其中某个环节解决不当,都可能会被当作漏洞来利用,从而导致整个验证方案被攻破。
为了验证技术方案的有效性,可以持续观察活动 API 接口的请求成功率。从请求成功率的数据中进一步分析“误伤”和“阻拦”的数据,以进一步确定能否要对方案进行调优。
通过上述的人机识别验证的组合方案,可以大幅提升活动 Web 页面的安全性。在活动 Web 页面应作为一个标准化的安全防范流程,除了美团,像淘宝和天猫也有相似的流程。因为活动经营的环节和方法多且复杂,仅仅提升了 Web 页面也不敢保证就是铁板一块,安全需要关注的环节还很多,安全攻防是一项长期的“拉锯更新战”,安全防范措施也需要持续地优化更新。
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 活动 Web 页面人机识别验证的探究与实践