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

在任何涉及交易的系统中,客户与商家之间的交易数据具有核心作用,如购买商品的价格、数量、型号和优惠券等。在客户挑选商品的过程中,这些交易数据逐渐形成;待客户提交订单时,交易数据被商家接收,形成双方认可的订单。交易数据在形成过程中必须要有可靠的临时存储,而不可靠的存储会允许攻击者提交伪造的交易数据,使商家利益受损。

iFlow 业务安全加固平台 可以将交易过程中产生的数据动态保存在后端,这样攻击者仅仅依靠篡改前端数据,是无法通过后端的数据检查的。


以某个购物网站为例,在接收客户提交订单时,网站直接使用了之前产生的数据,而这些数据是能够被攻击者篡改的。使用 iFlow 可以在不修改网站源代码的前提下,实现交易数据在后端的自动保存和校验。

一、依赖前端数据的原始网站

原始网站在用户提交订单时直接使用之前的金额数据,攻击者能够使用专用工具提交任意的金额数据。

1.1 正常用户访问

在客户选好商品进入结算页面时,页面上显示了金额 (实付款) 数据,在表单的隐藏域中也包含了这个数据。

图1

客户点击提交订单按钮后,包括金额在内所有交易数据被传到后端并写入到订单记录中。

图2

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

表1

1.2 攻击者访问

攻击者使用 Burpsuite 工具来作为浏览器和网站之间的代理,Burpsuite 可以拦截报文并修改其中内容后再发出。

攻击者挑选商品的步骤和正常用户一样,在进入结算页面点击提交订单之前,打开 Burpsuite 的拦截按钮。

图3

点击提交订单之后,Burpsuite 拦截并显示出请求报文的内容,可以看到其中包含有金额数据。攻击者将这个数据修改后,向服务器端发出报文。

图4

电商网站产生了这条订单记录,可以看到:它的金额为攻击者篡改过的值。

图5

HTTP 协议层面交互如下:

表2

二、iFlow虚拟补丁后的网站

我们在 Web 服务器前部署 iFlow 业务安全加固平台,它有能力拦截、计算和修改双向 HTTP 报文并具备存储能力,成为 Web 应用的虚拟补丁。本例中,iFlow 通过在服务器端保存前面步骤所产生的数据,使得应用不再依赖于前端发出的信息。

2.1 正常用户访问

用户在进行结算时,iFlow 获得 Web 服务器发出的结算页面,从中提取出金额数据并将其保存在服务器端缓存中。正常用户在提交订单时,提交中的金额值应该与缓存中的金额值一致。

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

表3

2.2 攻击者访问

如前所示,攻击者在提交订单时,会使用工具强行修改请求报文中金额数据的值。这个提交到达 iFlow 时,iFlow 会发现提交中的金额值与缓存中的金额值不一致,于是终止交易。

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

表4

2.3 代码

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

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

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

代码语言:txt
复制
[
	{
		"if": [
			"REQUEST_FILENAME == '/shopxo-1.6.0/index.php'",
			"@ARGS.s == '/index/buy/index'"
	    ],
		"then": {
			"execution": { 
				"directive": "setVariable", 
				"variable": "SESSION.payment_amount", 
				"value": "match(RESPONSE_BODY, 'class=\"nav-total-price\">(.*)</em>', 0, 1)"
			} 
		}
	},
	{
		"if": [ 
			"REQUEST_FILENAME == '/shopxo-1.6.0/index.php'",
			"@ARGS.s == '/index/buy/add.html'",
			"SESSION.payment_amount != @ARGS.price"
		],
		"then": { 
			"verdict": { 
				"action": "deny", 
				"log": "Price tampered: ${SESSION.payment_amount} => ${ARGS.price}" 
			} 
		} 
	}
]

示例代码中有两条规则,分别作用如下:

第一条规则

服务器返回结算页面时,iFlow 在响应报文中提取金额数值,并存放在此会话 (SESSION)的存储变量 payment_amount 中。

第二条规则

当浏览器请求提交订单时,iFlow 检查请求参数 price 的值与会话 (SESSION) 的存储变量 payment_amount 的值是否相等,如果不相等则阻止该用户的继续操作。

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

三、总结

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

通过这个例子可以看出,iFlow 与一般 WAF 的一个重要区别——iFlow 的规则是根据应用的实际情况和对安全功能的特定需求量身定制的,它不具备开箱即用的特点但却适合构造复杂的防护逻辑。(张戈 | 天存信息)