用户登录,几乎是所有 Web 应用所必须的环节。Web
应用通常会加入一些验证手段,以防止攻击者使用机器人自动登录,如要求用户输入图形验证码、拖动滑动条等。但是,如果验证的逻辑仅仅在前端执行,是很容易被攻击者绕过的。
iFlow 业务安全加固平台可以为只使用前端验证的应用打上动态虚拟补丁,使之成为需要前后端配合执行的验证逻辑,大幅度提高攻击者的攻击难度。

以某个开源购物网站为例,其管理员后台登录只使用了前端验证。我们尝试一下,如何在不修改网站源代码的前提下,使用iFlow实现前后端配合身份验证。

<>一、前端验证的原始网站

原始网站设置了滑动条拖动验证,但仅使用了前端验证,极易被攻击者甚至一般用户绕过。

<>1.1 正常用户访问

网站管理员在输入账号和口令后,必须拖动下方的滑动条到最右端,才能点击登录按钮发送登录信息。

反映在 HTTP 协议层面,是如下交互的:
正常用户 浏览器 Web服务器 地址栏输入:/shopx/admin.php 请求:/shopx/admin.php 返回:登录页面
请求:/shopx/js/drag.js 返回:drag.js 显示:登录页面 填写账号口令 拖动滑动条 设置前端元素 点击登录按钮
前端元素验证通过 发送:登录信息 返回:登录结果页面 显示:登录结果页面 正常用户 浏览器 Web服务器

在实现上,当用户将滑动条拖到最右端时,前端代码将 DOM 中的一个数据元素 validate-status 的值设置为 1。

<>1.2 攻击者访问

使用浏览器自带的开发者工具 (F12) 或者使用浏览器自动化工具 (如 WebDriver) ,将数据元素 validate-status 的值直接设置为 1


下图显示的是仅使用浏览器自带工具来修改元素:

如此,攻击者无需实际拖动滑动条验证,同样能够发出登录信息。HTTP 协议层面交互如下:
攻击者 浏览器 Web服务器 地址栏输入:/shopx/admin.php 请求:/shopx/admin.php 返回:登录页面
请求:/shopx/js/drag.js 返回:drag.js 显示:登录页面 填写账号口令 【自行修改前端元素】 点击登录按钮 前端元素验证通过
发送:登录信息 返回:登录结果页面 显示:登录结果页面 攻击者 浏览器 Web服务器

<>二、iFlow虚拟补丁后的网站

我们在 Web 服务器前部署 iFlow 业务安全加固平台,它有能力拦截、计算和修改双向 HTTP 报文并具备存储能力,成为 Web
应用的虚拟补丁。本例中,iFlow 通过在前端动态插入代码和在后端基于会话的状态保存,使得滑动条验证逻辑在前后端同时进行。

<>2.1 正常用户访问

iFlow 在前端的拖动滑动条前端脚本中动态插入了一段代码,使得用户在完成拖动滑动条时,浏览器自动向 iFlow 发送一条信息并被 iFlow
保存为一个标记。用户在发送登录信息时,iFlow 检查该标记,对于一个正常用户,这个标记一定是存在的,于是登录过程正常继续。

正常用户的 HTTP 协议交互过程如下:
正常用户 浏览器 iFlow Web服务器 地址栏输入:/shopx/admin.php 请求:/shopx/admin.php 返回:登录页面
请求:/shopx/js/drag.js 返回:drag.js 修改:在drag.js插入代码 显示:登录页面 填写账号口令 拖动滑动条
设置前端元素 请求:/iflow/dragged.dummy 为会话设置drag_ok标志 点击登录按钮 前端元素验证通过 发送:登录信息
会话中有drag_ok标志 发送:登录信息 返回:登录结果页面 显示:登录结果页面 正常用户 浏览器 iFlow Web服务器

<>2.2 攻击者访问

如前所示,攻击者强行修改前端元素,可以通过前端验证。但当发送登录信息而 iFlow
检查标记时,由于攻击者之前并未实际拖动滑动条发送标记请求,因此该标记并不存在。iFlow 可以据此判断这是一个攻击者在访问,于是终止登录过程。

攻击者的 HTTP 协议交互过程如下:
攻击者 浏览器 iFlow Web服务器 地址栏输入:/shopx/admin.php 请求:/shopx/admin.php 返回:登录页面
请求:/shopx/js/drag.js 返回:drag.js 修改:在drag.js中插入代码 显示:登录页面 填写账号口令 【自行修改前端元素】
点击登录按钮 前端元素验证通过 发送:登录信息 会话中无drag_ok标志 拒绝访问 拒绝访问 攻击者 浏览器 iFlow Web服务器

<>2.3 代码

iFlow 内置的 W2 语言是一种专门用于实现 Web 应用安全加固的类编程语言。它介于配置和通用语言之间,具备编程的基本要素和针对 HTTP
协议的特有扩展,能为业务系统编写涉及复杂判断和动态修改的逻辑。

考虑到安全产品的使用者通常为非程序员,他们习惯面对配置文件而非一段代码。因此,W2
语言虽包含语言要素,仍以规则文件方式呈现,并采用可以体现层次结构和方便词法校验的 JSON 格式。

用 W2 语言实现上述虚拟补丁的代码如下:
[ { "if": [ "REQUEST_FILENAME == '/shopx/js/drag.js'" ], "then": { "execution":
{ "directive": "alterResponseBody", "op": "string", "target": "function
dragOk(){", "substitute": "function dragOk(){$.get('/iflow/dragged.dummy');" } }
}, { "if": [ "REQUEST_FILENAME == '/iflow/dragged.dummy'" ], "then": {
"execution": [ "SESSION.drag_ok@60 = true" ] } }, { "if": [ "REQUEST_FILENAME
== '/shopx/admin.php'", "@ARGS.s == 'login'", "!SESSION.drag_ok" ], "then": {
"verdict": { "action": "deny", "log": "Drag verifycode is not ok!" } } } ]
示例代码中有三条规则,分别作用如下——

第一条规则

当浏览器请求 drag.js 时,iFlow 拦截响应报文,在 dragOK()
函数中插入一个代码片段,其作用是当用户拖拽验证框完成后向服务器发送一条验证请求,即下一条规则中的/iflow/dragged.dummy;

第二条规则

当浏览器请求 /iflow/dragged.dummy 时 (用户拖动完成后由 dragOK() 函数自动发出),iFlow 拦截此请求,将该会话
(SESSION) 存储中的 drag_ok 标志设置为 true ;

第三条规则

当用户点击登录按钮时发出请求时,iFlow 拦截此请求,检查会话 (SESSION) 存储中的 drag_ok 标志是否为 true
(正常用户操作在上一条规则中应该被设置),如果不为 true 则 iFlow 阻止该用户的继续操作。

注意:上述会话中的 drag_ok 标志是保存在服务器端的 iFlow 存储中的,在浏览器端是看不到数据更无法进行修改的。

<>三、总结

iFlow 使用三条规则在不修改服务器端代码的前提下,透明地实现了在后端执行的拖动验证逻辑。

此外我们可以看到,iFlow 的规则是根据应用的实际情况和对安全功能的特定需求量身定制的,它不具备开箱即用的特点但却适合构造复杂的防护逻辑。

当然,这仅是一个入门的例子,主要是为了体现防御思路和 iFlow 的能力。聪明的读者一定会想到——攻击者可以针对这个防御手段采取对应的攻击方式
(如主动发出后端验证请求),而防御者也可以将防御手段制作得更高明一些 (如 js 混淆、检查滑动速度和时间等)
,这些我们在以后的例子中再慢慢展开。至少,比起原始的网站系统,现在攻击者没那么容易欺骗 Web 应用了。

技术
©2019-2020 Toolsou All rights reserved,
uni-app中使用 async + await 实现异步请求同步化Dart中的Isolate十分钟掌握Pytorch搭建神经网络的流程利用python对monkey日志完成自动化分析二进制模2除法(CRC循环冗余检验)vue实现pc端的自适应,rem适配希尔排序Unity面试经验(两天面六家,四个offer,济南)C++实现《走迷宫》小游戏VR、AR和MR这些技术的区别