活动 Web 页面人机识别验证的探索与实践

在电商行业,线上的营销活动特别多。在移动互联网时代,通常为了活动的快速上线和内容的即时更新,大部分的业务场景仍然经过 Web 页面来承载。但因为 Web 页面天生“环境透明”,相较于移动客户端页面在安全性上存在更大的挑战。本文主要以移动端 Web 页面为基础来说述如何提高页面安全性。html

活动 Web 页面的安全挑战

对于营销活动类的 Web 页面,领券、领红包、抽奖等活动方式很常见。此类活动对于普通用户来讲大多数时候就是“拼手气”,而对于非正经常使用户来讲,能够经过直接刷活动 API 接口的“做弊”方式来提高“手气”。这样的话,对普通用户来讲,就变得很不公平。前端

对于活动运营的主办方来讲,若是风控措施作的很差,这类刷接口的“拼手气”方式可能会对企业形成较大的损失。如原本计划按 7 天发放的红包,在上线 1 天就被刷光了,活动的营销成本就会被意外提高。主办方想发放给用户的满减券、红包,却大部分被黄牛使用自动脚本刷走,而真正想参与活动的用,却没法享受活动优惠。web

终端用户究竟是人仍是机器,网络请求是否为真实用户发起,是否存在安全漏洞而且已被“羊毛党”恶意利用等等,这些都是运营主办方要担忧的问题。算法

安全防范的基本流程

为了提高活动 Web 页面的安全性,一般会引入专业的风控服务。引入风控服务后,安全防御的流程大体如图所示。segmentfault

  • 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)都是为了确保人机识别验证不被破解而作的安全防范。接下来,本文会分别针对这三个技术挑战来讲明如何设计技术方案。

挑战一:根据用户使用场景来定制人机识别验证算法

先来分析一下用户的使用场景,正经常使用户参与活动的步骤是用户进入活动页面后,会有短暂的停留,而后点击按钮参与活动。这里所说的“参与活动”,最终都会在活动页面发起一个接口的请求。若是是非正经常使用户,能够直接跳过以上的实际动做而去直接请求参与活动的接口。

那么区别于正经常使用户和非正经常使用户就是那些被跳过的动做,对实际动做进一步概括以下:

  1. 进入页面。
  2. 短暂的停留。
  3. 滚动页面。
  4. 点击按钮。

以上的动做又能够分为必需的操做和可选的操做。对这一连串动做产生的日志数据进行收集,在请求参与活动的接口时,将这些数据提交至后端,验证其合法性。这就是一个简单的人机识别验证。

在验证动做的合法性时,须要考虑到这些动做数据是否是能被轻易模拟。另外,动做的发生应该有一条时间线,能够给每一个动做都增长一个时间戳,好比点击按钮确定是在进入页面以后发生的。

一些特定的动做的日志数据也会有合理的区间,进入页面的动做若是以 JS 资源加载的时间为基准,那么加载时间可能大于 100 毫秒,小于 5 秒。而对于移动端的按钮点击,点击时记录的坐标值也会有对应的合理区间,这些合理的区间会根据实际的环境和状况来进行设置。

除此以外,设备环境的数据也能够进行收集,包括用户参与活动时使用的终端类型、浏览器的类型、浏览器是否为客户端的容器等,若是使用了客户端,客户端是否会携带特殊的标识等。

最后,还能够收集一些“无效”的数据,这些数据用于障人耳目,验证算法会将其忽略。尽管收集数据的动做是透明的,可是验证数据合法性不是透明的,攻击者没法知道,验证的算法中怎么区分哪些是有效、哪些是无效。这已经有点“蜜罐数据”的意思了。

挑战二:确保通讯的安全性

收集的敏感数据要发送给风控服务端,进而确保通讯过程的安全。

  1. Web API 接口不能被中途拦截和篡改,通讯协议使用 HTTPS 是最基本的要求;同时还要让服务端生成惟一的 Token,在通讯过程当中都要携带该 Token。
  2. 接口携带的敏感数据不能是明文的,敏感数据要进行加密,这样攻击者没法经过网络抓包来详细了解敏感数据的内容。

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 页面也不敢保证就是铁板一块,安全须要关注的环节还不少,安全攻防是一项长期的“拉锯升级战”,安全防范措施也须要持续地优化升级。

参考资料

做者简介

益国,美团点评 Web 前端开发工程师。2015年加入美团,曾前后负责过风控前端SDK和活动运营平台的研发,现负责大数据平台的研发工做。

相关文章
相关标签/搜索