服务器端业务逻辑,特别是涉及数据库读写时,存在着关键步骤的时序问题,如果设计或代码编写不当就可能存在竞争条件漏洞。攻击者可以利用多线程并发技术,在数据库的余额字段更新之前,同时发起多次兑换积分或购买商品请求,从中获取利益。本文将讨论如何简单地使用 iFlow 应用安全加固平台的可编程特性,对竞争条件产生的支付漏洞进行防护。

一、原始网站

这是一个在支付环节存在竞争条件漏洞的站点:用户输入一个支付数值,系统将这个数值与余额比较,如果支付数值小于余额则允许支付,并从余额中减去支付数值。

攻击者编写并执行了一个 Python 攻击脚本,使用多线程并发对支付请求 URL 进行访问。由于未能正确处理竞争条件问题,系统为多个请求同时扣除了余额。我们回到浏览器中刷新页面,可以发现余额变为了 -10 元,如下图所示。

HTTP 交互流程如下:

sequenceDiagram
participant 攻击者
participant 浏览器
participant 攻击工具
participant Web服务器
participant 数据库
攻击者->>浏览器: 点击“竞争条件-支付”链接
浏览器->>Web服务器: GET /race_condition/pay.php
数据库->>Web服务器: 读取金额
Web服务器->>浏览器: 返回“竞争条件-支付”页面
浏览器->>攻击者: 显示:余额为10元
攻击者->>攻击工具: 执行多线程并发请求
rect rgb(250, 128, 128)
攻击工具->>Web服务器: POST /race_condition/pay.php
Web服务器->>数据库: 余额足够,扣除支付金额
攻击工具->>Web服务器: POST /race_condition/pay.php
Web服务器->>数据库: 余额足够,扣除支付金额
攻击工具->>Web服务器: POST /race_condition/pay.php
Web服务器->>数据库: 余额足够,扣除支付金额
end
攻击者->>浏览器: 点击“竞争条件-支付”链接
浏览器->>Web服务器: GET /race_condition/pay.php
数据库->>Web服务器: 读取金额
Web服务器->>浏览器: 返回“竞争条件-支付”页面
浏览器->>攻击者: 显示:余额为-4元

二、iFlow虚拟补丁后的网站

我们在 Web 服务器前部署 iFlow 业务安全加固平台,它有能力拦截、计算和修改双向 HTTP 报文并具备存储能力,成为 Web 应用的虚拟补丁。本例中,iFlow 使用一个全局唯一的定时标志来阻止对并发请求的同时处理。

每个支付请求到来时,iFlow 都会检查定时标志是否存在。只有标志不存在时才交给 Web 服务器处理这个请求,并同时设置定时标志。在定时期间,如有其他支付请求到来,而 iFlow 检查到定时标志存在,则会放弃处理这个请求,将用户重定向到指定页面。定时结束后,系统则又可以处理下一个支付请求。

HTTP 协议交互过程如下:

sequenceDiagram
participant 攻击者
participant 浏览器
participant 攻击工具
participant iFlow
participant Web服务器
participant 数据库
攻击者->>浏览器: 点击“竞争条件-支付”链接
浏览器->>Web服务器: GET /race_condition/pay.php
数据库->>Web服务器: 读取金额
Web服务器->>浏览器: 返回“竞争条件-支付”页面
浏览器->>攻击者: 显示:余额为10元
攻击者->>攻击工具: 执行多线程并发请求脚本
攻击工具->>iFlow: POST /race_condition/pay.php
Note over iFlow: 设置定时标志
iFlow->>Web服务器: POST /race_condition/pay.php
Web服务器->>数据库: 余额足够,扣除支付金额
rect rgb(250, 128, 128)
攻击工具->>iFlow: POST /race_condition/pay.php
end
Note over iFlow: 定时标志存在,重定向页面
rect rgb(250, 128, 128)
攻击工具->>iFlow: POST /race_condition/pay.php
end
Note over iFlow: 定时标志存在,重定向页面
攻击工具->>iFlow: POST /race_condition/pay.php
Note over iFlow: 定时标志超时后不存在
iFlow->>Web服务器: POST /race_condition/pay.php
Web服务器->>数据库: 余额不足,不执行支付
攻击者->>浏览器: 点击“竞争条件-支付”链接
浏览器->>Web服务器: GET /race_condition/pay.php
数据库->>Web服务器: 读取金额
Web服务器->>浏览器: 返回“竞争条件-支付”页面
浏览器->>攻击者: 显示:余额为0元

代码

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

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

用 W2 语言实现上述虚拟补丁的代码如下:

{
"if": [
"REQUEST_FILENAME == '/race_condition/pay.php'",
"REQUEST_METHOD == 'POST'"
],
"then": {
"if": "GLOBAL.pay_time_flag",
"then": {
"verdict": {
"action": "redirect",
"param": "/retry.html"
}
},
"else": "GLOBAL.pay_time_flag@2=1"
}
}

示例代码中,当服务器端收到支付请求时,iFlow 拦截此请求。iFlow 会检查全局 (GLOBAL) 存储变量 pay_time_flag 是否存在:如存在,则重定向到页面 /retry.html (向正常用户提示稍后重试);如不存在,则设置一个生命时长为2秒 (数值可根据实际请求处理所需时间调整) 的存储变量 pay_time_flag

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

三、总结

使用 iFlow 书写一条规则,即可实现在设定时间内只允许处理一个请求,避免竞争条件带来的异常处理。(张戈 | 天存信息)

最新文章

  1. Oracle 查询出来的数据取第一条
  2. .NET设计模式(2):1.2 抽象工厂模式(Abstract Factory)
  3. NPOI分层导出
  4. Tables without a clustered index are not supported in this version of SQL Server. Please create a clustered index and try again.
  5. 使用ab进行压力测试
  6. 取得 APP 自己的版本号 (狠跨 4 个平台)
  7. easyui plugin——etreegrid:CRUD Treegrid
  8. Sqli-labs less 58
  9. HNOI2010弹飞绵羊
  10. 浏览器编辑HTML
  11. C#获取QQ旋风的下载记录
  12. oracle 中的select ...connect by prior ...start with 及(+)的用法
  13. 一步一步的理解C++STL迭代器
  14. 近期ubuntu 14.04 cpu占用高排障
  15. Linux环境搭建 | 手把手教你如何安装CentOS7虚拟机
  16. samba故障:protocol negotiation failed: NT_STATUS_IO_TIMEOUT
  17. kafka环境搭建和使用(python API)
  18. webstorm安装教程
  19. linux中截取文件的特定字节(去掉utf-8 bom头)
  20. nginx记录post数据日志

热门文章

  1. 【NX二次开发】Block UI 指定矢量
  2. 【NX二次开发】设置了“附加包含目录”,还是提示“无法打开包括文件”的解决方法
  3. 终于明白为什么要加 final 关键字了
  4. 题解 P3940 分组
  5. 【模拟7.22】visit(卢卡斯定理&&中国剩余定理)
  6. Oracle对大表进行delete注意事项
  7. 『无为则无心』Python基础 — 9、Python字符串的编码与转义
  8. VueJs(16)---Nuxt引入mavon-editor插件实现markdown功能
  9. 全新安装Windows版 Atlassian Confluence 7.3.1 + MySQL 8.0,迁移数据,并设置服务自启
  10. AcWing 1275. 最大数