用户登录,几乎是所有 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. 测开之Python自动化全栈工程师+性能专项(送思维导图)

    测开之Python自动化全栈工程师+性能专项 功能测试基础 接口测试基础接口的通信原理与本质cookie.session.token详解接口测试的意义与测试方法接口测试用例的设计 app测试 app流 ...

  2. Jmeter和Postman做接口测试的区别,孰优孰劣?

    区别1:用例组织方式 不同的目录结构与组织方式代表不同工具的测试思想,学习一个测试工具应该首先了解其组织方式. Jmeter的组织方式相对比较扁平,它首先没有WorkSpace(工作空间)的概念,直接 ...

  3. 这次我好像才真的明白了CSS Rem字体计算的原理

    背景 如何按照设计稿中标注的尺寸,直接写页面的样式,不再需要px2rem这样的工具或者人工转换 ? 只要你明白了rem的计算原理,这个问题的答案超级简单. 根字体大小计算核心原理 设备的根字体大小 * ...

  4. Go的Waitgroup和锁

    学 Go 的时候知道 Go 语言支持并发,最简单的方法是通过 go 关键字开启 goroutine 即可.可在工作中,用的是 sync 包的 WaitGroup,然而这样还不够,当多个 gorouti ...

  5. 3D深色金属哥特3D项目工具小图标icon高清设计素材

    3D深色金属哥特3D项目工具小图标icon高清设计素材

  6. shell脚本就是由Shell命令组成的执行文件,将一些命令整合到一个文件中,进行处理业务逻辑,脚本不用编译即可运行。它通过解释器解释运行,所以速度相对来说比较慢。

    shell脚本?在说什么是shell脚本之前,先说说什么是shell. shell是外壳的意思,就是操作系统的外壳.我们可以通过shell命令来操作和控制操作系统,比如Linux中的Shell命令就包 ...

  7. maven build和push image中遇到的坑(学习过程记录)

    最近在做jenkins的持续集成构建,其中一项是要实现docker容器化部署.项目本身是maven项目,我对于maven和docker都没有什么认知基础,于是求助百度和官网,从头开始啃起.遇到了不少的 ...

  8. DOCKER学习_016:Docker镜像仓库和HARBOR的简单安装和管理

    一 镜像仓库介绍 1.1 简介 镜像仓库用于存放 Docker镜像 Docker registry提供镜像仓库服务 一个 Docker registry可以包含多个镜像仓库 仓库分为公共镜像仓库与私有 ...

  9. VFB FEEDBACK

  10. Centos7 rsync同步备份文件

    Centos7 rsync同步备份文件 一.rsync主服务端 1,安装rsync 查看是否安装rsync [root@localhost /]# rpm -qa | grep rsync 在线安装r ...