Java SpringBoot框架代码审计七 - 逻辑漏洞

逻辑漏洞不像之前介绍的漏洞有一套固定的审计流程,每个逻辑漏洞背后的代码都不一样。通过纯白盒去找逻辑漏洞是比较费劲的,首先需要彻底了解业务,再带着各种疑问和奇怪的想法去审。

逻辑漏洞代码审计过程

用户正常的购物过程是添加购物车->下单->付款->出库->交易成功,但程序在购物过程中没有对前一步进行校验。下订单但未支付时,访问/orders/{orderNo}/finish可直接完成交易。

1
2
3
4
5
6
7
8
9
10
11
12
// /src/main/java/ltd/newbee/mall/controller/mall/OrderController.java
@PutMapping("/orders/{orderNo}/finish")
@ResponseBody
public Result finishOrder(@PathVariable("orderNo") String orderNo, HttpSession httpSession) {
NewBeeMallUserVO user = (NewBeeMallUserVO) httpSession.getAttribute(Constants.MALL_USER_SESSION_KEY);
String finishOrderResult = newBeeMallOrderService.finishOrder(orderNo, user.getUserId());
if (ServiceResultEnum.SUCCESS.getResult().equals(finishOrderResult)) {
return ResultGenerator.genSuccessResult();
} else {
return ResultGenerator.genFailResult(finishOrderResult);
}
}

从代码中可以看到直接调用newBeeMallOrderService.finishOrder(orderNo, user.getUserId()),对于该订单是否支付,是否出库等过程都没有校验。

实际测试

随便添加一件物品到购物车,提交订单

submit-order

此时来到订单详情页面,按正常逻辑来下一步是付款操作

pay-order

在管理页面确认该订单当前状态是待支付

wait-for-payment

使用PUT方法访问http://localhost:8089/orders/15886680589866584/finish即可直接完成订单

bypass-pay-order

因为代码使用的是@PutMapping,所以只能使用PUT方法访问,其他请求方法不会被执行

finishOrder

再次查看订单,已经交易成功

paid-success

在管理页面查看该订单,证明交易成功。

show-orders