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


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

一、前端验证的原始网站

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

1.1 正常用户访问

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

反映在 HTTP 协议层面,是如下交互的:

sequenceDiagram
participant 正常用户
participant 浏览器
participant Web服务器
正常用户->>浏览器: 地址栏输入:/shopx/admin.php
浏览器->>Web服务器: 请求:/shopx/admin.php
Web服务器->>浏览器: 返回:登录页面
浏览器->>Web服务器: 请求:/shopx/js/drag.js
Web服务器->>浏览器: 返回:drag.js
浏览器->>正常用户: 显示:登录页面
正常用户->>浏览器: 填写账号口令
正常用户->>浏览器: 拖动滑动条
Note over 浏览器: 设置前端元素
正常用户->>浏览器: 点击登录按钮
Note over 浏览器: 前端元素验证通过
浏览器->>Web服务器: 发送:登录信息
Web服务器->>浏览器: 返回:登录结果页面
浏览器->>正常用户: 显示:登录结果页面

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

1.2 攻击者访问

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

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

如此,攻击者无需实际拖动滑动条验证,同样能够发出登录信息。HTTP 协议层面交互如下:

sequenceDiagram
participant 攻击者
participant 浏览器
participant Web服务器
攻击者->>浏览器: 地址栏输入:/shopx/admin.php
浏览器->>Web服务器: 请求:/shopx/admin.php
Web服务器->>浏览器: 返回:登录页面
浏览器->>Web服务器: 请求:/shopx/js/drag.js
Web服务器->>浏览器: 返回:drag.js
浏览器->>攻击者: 显示:登录页面
攻击者->>浏览器: 填写账号口令
rect rgb(250, 128, 128)
攻击者->>浏览器: 【自行修改前端元素】
end
攻击者->>浏览器: 点击登录按钮
Note over 浏览器: 前端元素验证通过
浏览器->>Web服务器: 发送:登录信息
Web服务器->>浏览器: 返回:登录结果页面
浏览器->>攻击者: 显示:登录结果页面

二、iFlow虚拟补丁后的网站

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

2.1 正常用户访问

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

正常用户的 HTTP 协议交互过程如下:

sequenceDiagram
participant 正常用户
participant 浏览器
participant iFlow
participant Web服务器
正常用户->>浏览器: 地址栏输入:/shopx/admin.php
浏览器->>Web服务器: 请求:/shopx/admin.php
Web服务器->>浏览器: 返回:登录页面
浏览器->>Web服务器: 请求:/shopx/js/drag.js
Web服务器->>iFlow: 返回:drag.js
rect rgb(160, 250, 160)
iFlow->>浏览器: 修改:在drag.js插入代码
end
浏览器->>正常用户: 显示:登录页面
正常用户->>浏览器: 填写账号口令
正常用户->>浏览器: 拖动滑动条
Note over 浏览器: 设置前端元素
浏览器->>iFlow: 请求:/iflow/dragged.dummy
rect rgb(160, 250, 160)
Note over iFlow: 为会话设置drag_ok标志
end
正常用户->>浏览器: 点击登录按钮
Note over 浏览器: 前端元素验证通过
浏览器->>iFlow: 发送:登录信息
rect rgb(160, 250, 160)
Note over iFlow: 会话中有drag_ok标志
end
iFlow->>Web服务器: 发送:登录信息
Web服务器->>浏览器: 返回:登录结果页面
浏览器->>正常用户: 显示:登录结果页面

2.2 攻击者访问

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

攻击者的 HTTP 协议交互过程如下:

sequenceDiagram
participant 攻击者
participant 浏览器
participant iFlow
participant Web服务器
攻击者->>浏览器: 地址栏输入:/shopx/admin.php
浏览器->>Web服务器: 请求:/shopx/admin.php
Web服务器->>浏览器: 返回:登录页面
浏览器->>Web服务器: 请求:/shopx/js/drag.js
Web服务器->>iFlow: 返回:drag.js
rect rgb(160, 250, 160)
iFlow->>浏览器: 修改:在drag.js中插入代码
end
浏览器->>攻击者: 显示:登录页面
攻击者->>浏览器: 填写账号口令
rect rgb(250, 128, 128)
攻击者->>浏览器: 【自行修改前端元素】
end
攻击者->>浏览器: 点击登录按钮
Note over 浏览器: 前端元素验证通过
浏览器->>iFlow: 发送:登录信息
rect rgb(160, 250, 160)
Note over iFlow: 会话中无drag_ok标志
end
iFlow->>浏览器: 拒绝访问
rect rgb(250, 128, 128)
浏览器->>攻击者: 拒绝访问
end

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 应用了。(张戈 | 天存信息)

WEB安全新玩法 [2] 防范前端验证绕过的更多相关文章

  1. WEB安全新玩法 [6] 防范图形验证码重复使用

    在完成关键业务操作时,要求用户输入图形验证码是防范自动化攻击的一种措施.为安全起见,即使针对同一用户,在重新输入信息时也应该更新图形验证码.iFlow 业务安全加固平台可以加强这方面的处理. 某网站系 ...

  2. WEB安全新玩法 [5] 防范水平越权之查看他人订单信息

    水平越权是指系统中的用户在未经授权的情况下,查看到另一个同级别用户所拥有的资源.水平越权会导致信息泄露,其产生原因是软件业务设计或编码上的缺陷.iFlow 业务安全加固平台可以缓解部分场景下的水平越权 ...

  3. WEB安全新玩法 [10] 防范竞争条件支付漏洞

    服务器端业务逻辑,特别是涉及数据库读写时,存在着关键步骤的时序问题,如果设计或代码编写不当就可能存在竞争条件漏洞.攻击者可以利用多线程并发技术,在数据库的余额字段更新之前,同时发起多次兑换积分或购买商 ...

  4. WEB安全新玩法 [1] 业务安全动态加固平台

    近年来,信息安全体系建设趋于完善,以注入攻击.跨站攻击等为代表的传统 Web 应用层攻击很大程度上得到了缓解.但是,Web 应用的业务功能日益丰富.在线交易活动愈加频繁,新的安全问题也随之呈现:基于 ...

  5. WEB安全新玩法 [9] 重置密码之验证流程防绕过

    一般来说,业务流程中出现多个操作环节时,是需要顺序完成的.程序设计者往往按照正常用户的操作顺序实现功能,而忽略了攻击者能够绕过中途环节,直接在后续环节上进行非法操作.iFlow 业务安全加固平台能够在 ...

  6. WEB安全新玩法 [3] 防护交易数据篡改

    在任何涉及交易的系统中,客户与商家之间的交易数据具有核心作用,如购买商品的价格.数量.型号和优惠券等.在客户挑选商品的过程中,这些交易数据逐渐形成:待客户提交订单时,交易数据被商家接收,形成双方认可的 ...

  7. WEB安全新玩法 [4] 防护邮箱密码重置漏洞

    大部分具有账号系统的应用都会提供重置用户登录密码的功能,常见方式之一是:用户输入自己的邮箱地址或手机号,应用向这个邮箱或手机号发送验证码,用户将收到的验证码输入应用中即可完成密码重置.这一过程容易因设 ...

  8. WEB安全新玩法 [8] 阻止订单重复提交

    交易订单的重复提交虽然通常不会直接影响现金流和商品流,但依然会给网站运营方带来损害,如消耗系统资源.影响正常用户订单生成.制造恶意用户发起纠纷的机会等.倘若订单对象是虚拟商品,也有可能造成实际损失.订 ...

  9. 自定义 checkbox 新玩法 ?

    自定义 checkbox 新玩法 ? 第一步:selector 编写 drawable/selector_checkbox_voice.xml <?xml version="1.0&q ...

随机推荐

  1. Windows进程间通讯(IPC)----套接字

    Windows套接字 Windows套接字即socket,通过socket可以实现在不同的进程间通信,甚至这两个进程可以不在同一个计算机中. Winsock使用步骤 服务端 socket初始化 创建套 ...

  2. IPC机制key值的各位组成

    key_t ftok(const char *_pathname, int _proj_id) key值的第31~24位为ftok()第二个参数的低8位: key值的第23~16位为ftok()第一个 ...

  3. .Net·快速查找哪一个类库引用了哪一个Package

    阅文时长 | 0.18分钟 字数统计 | 348.8字符 主要内容 | 1.引言&背景 2.查找法示例 3.声明与参考资料 『.Net·快速查找哪一个类库引用了哪一个Package』 编写人 ...

  4. java集合类介绍

    目录 集合类简介 List ArrayList LinkedList Vector Stack Set HashSet LinkedHashSet TreeSet Map HashMap Hashta ...

  5. 对Linux系统内核版本稳定性测试介绍

    对Linux系统内核版本稳定性测试介绍 在对 Linux 内核版本稳定性的测试中,需要明确地声明并证明为什么版本是稳定的或者是不稳定的. 然而还没有被证明和证实当前现有的系统范围内的压力测试可以测试 ...

  6. 更新索引库: $locate string 寻找包含有string的路径: $updatedb

    更新索引库: $locate string 寻找包含有string的路径: $updatedb 与find不同,locate并不是实时查找.你需要更新数据库,以获得最新的文件索引信息.

  7. Mysql_源码包安装详细过程

    一.mysql安装 1.二进制安装 2.源码包安装 3.rpm包安装 1.源码包安装 1)上传或下载源码包 [root@db02 ~]# rz mysql-5.6.46.tar.gz 2)安装依赖 由 ...

  8. 云计算OpenStack核心组件---horizon Web管理界面(9)

    一.horizon介绍 Horizon 为 Openstack 提供一个 WEB 前端的管理界面 (UI 服务 )通过 Horizone 所提供的 DashBoard 服务 , 管理员可以使用通过 W ...

  9. C语言变量和函数命名规范

    C 语言变量和函数命名规范: 关于C语言变量和函数命名规范 据考察,没有一种命名规则可以让所有的程序员赞同,程序设计教科书一般都不指定命名规则.命名规则对软件产品而言并不是"成败悠关&quo ...

  10. 11.7 iostat: I/O信息统计

    iostat是I/O statistics(输入/输出统计)的缩写,其主要功能是对系统的磁盘I/O操作进行监视.它的输出主要是显示磁盘读写操作的统计信息,同时也会给出CPU的使用情况.同vmstat命 ...