Просмотр исходного кода

fix: 修复订单/地址越权及支付类型绕过漏洞

Co-authored-by: Cursor <cursoragent@cursor.com>
15376779826 3 недель назад
Родитель
Сommit
6ff012ee03

+ 27 - 0
fs-service-system/src/main/java/com/fs/store/service/impl/FsStoreOrderServiceImpl.java

@@ -420,6 +420,10 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService
         if(!Objects.equals(order.getStatus(), OrderInfoEnum.STATUS_0.getValue())){
             return R.error("订单状态不正确");
         }
+        R payTypeError = validateAppPayType(param.getPayType());
+        if (payTypeError != null) {
+            return payTypeError;
+        }
 
         Object isPaying = redisCache.getCacheObject("isPaying:" + param.getOrderId());
         if(ObjectUtil.isNotNull(isPaying)) {
@@ -824,6 +828,12 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService
             List<FsStoreCartQueryVO> carts = redisCache.getCacheObject("orderCarts:" + param.getOrderKey());
             //获取地址
             FsUserAddress address=userAddressMapper.selectFsUserAddressById(param.getAddressId());
+            if (address == null) {
+                return R.error("地址不存在");
+            }
+            if (!Objects.equals(address.getUserId(), userId)) {
+                return R.error("非法操作");
+            }
             //检测库存
             //三种特定产品发YDSP001
             int ydspHouse = 0;
@@ -1603,6 +1613,9 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService
             //获取地址
             FsUserAddress address=userAddressMapper.selectFsUserAddressById(param.getAddressId());
             Asserts.notNull(address,"当前地址不存在,请检查是否有维护!");
+            if (!Objects.equals(address.getUserId(), uid)) {
+                return R.error("非法操作");
+            }
             //获取套餐数据
             JSONArray jsonArray=JSONUtil.parseArray(storeProductPackage.getProducts());
             List<StorePackageProductDTO> goodsList=JSONUtil.toList(jsonArray,StorePackageProductDTO.class);
@@ -3711,6 +3724,10 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService
         if(order.getStatus()!= OrderInfoEnum.STATUS_0.getValue()){
             return R.error("订单状态不正确");
         }
+        R payTypeError = validateAppPayType(param.getPayType());
+        if (payTypeError != null) {
+            return payTypeError;
+        }
 
         Object isPaying =redisCache.getCacheObject("isPaying:"+order.getId());
         if(ObjectUtil.isNotNull(isPaying)){
@@ -3918,4 +3935,14 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService
         return R.error("无支付类型");
     }
 
+    /**
+     * 校验 App 端支付类型,禁止通过 payType=3(货到付款)绕过在线支付。
+     */
+    private R validateAppPayType(Integer payType) {
+        if (Objects.equals(payType, 3)) {
+            return R.error("不支持该支付方式");
+        }
+        return null;
+    }
+
 }

+ 15 - 0
fs-user-app/src/main/java/com/fs/app/controller/AppBaseController.java

@@ -2,6 +2,7 @@ package com.fs.app.controller;
 
 
 import com.fs.app.utils.JwtUtils;
+import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.StringUtils;
@@ -34,4 +35,18 @@ public class AppBaseController {
 			return null;
 		}
 	}
+
+	protected boolean isCurrentUser(Long userId) {
+		if (userId == null || StringUtils.isEmpty(getUserId())) {
+			return false;
+		}
+		return userId.equals(Long.parseLong(getUserId()));
+	}
+
+	protected R denyIfNotCurrentUser(Long userId) {
+		if (!isCurrentUser(userId)) {
+			return R.error("非法操作");
+		}
+		return null;
+	}
 }

+ 15 - 1
fs-user-app/src/main/java/com/fs/app/controller/StoreAfterSalesController.java

@@ -42,8 +42,15 @@ public class StoreAfterSalesController extends  AppBaseController {
     @ApiOperation("获取订单项列表")
     @GetMapping("/getMyStoreOrderItemByOrderId")
     public R getMyStoreOrderById(@RequestParam("orderId") Long orderId){
-        List<FsStoreOrderItemVO> list=itemService.selectFsStoreOrderItemListByOrderId(orderId);
         FsStoreOrder order=orderService.selectFsStoreOrderById(orderId);
+        if (order == null) {
+            return R.error("订单不存在");
+        }
+        R denied = denyIfNotCurrentUser(order.getUserId());
+        if (denied != null) {
+            return denied;
+        }
+        List<FsStoreOrderItemVO> list=itemService.selectFsStoreOrderItemListByOrderId(orderId);
         order.setUserPhone(ParseUtils.parsePhone(order.getUserPhone()));
         order.setUserAddress(ParseUtils.parseIdCard(order.getUserAddress()));
         return R.ok().put("order", order).put("items",list);
@@ -87,6 +94,13 @@ public class StoreAfterSalesController extends  AppBaseController {
     @ApiOperation(value = "获取售后详情", notes = "获取售后详情")
     public R getAfterSalesDetails(@RequestParam("salesId") Long id) {
         FsStoreAfterSales sales=storeAfterSalesService.selectFsStoreAfterSalesById(id);
+        if (sales == null) {
+            return R.error("售后单不存在");
+        }
+        R denied = denyIfNotCurrentUser(sales.getUserId());
+        if (denied != null) {
+            return denied;
+        }
         FsStoreAfterSalesItem map=new FsStoreAfterSalesItem();
         map.setStoreAfterSalesId(id);
         List<FsStoreAfterSalesItem>  items=salesItemService.selectFsStoreAfterSalesItemList(map);

+ 86 - 1
fs-user-app/src/main/java/com/fs/app/controller/StoreOrderController.java

@@ -6,6 +6,7 @@ import com.fs.common.annotation.RepeatSubmit;
 
 import com.fs.common.core.domain.R;
 import com.fs.common.exception.CustomException;
+import com.fs.common.utils.StringUtils;
 import com.fs.store.domain.*;
 import com.fs.store.dto.FsStoreOrderComputeDTO;
 
@@ -77,7 +78,20 @@ public class StoreOrderController extends  AppBaseController {
         if(ObjectUtil.isEmpty(orderId) && ObjectUtil.isEmpty(orderCode)){
             throw new CustomException("订单ID和订单号不能同时为空");
         }
-        return orderService.getMyStoreOrderByIdOrOrderCode(orderId,orderCode);
+        FsStoreOrder order;
+        if (StringUtils.isNotEmpty(orderCode)) {
+            order = orderService.selectFsStoreOrderByOrderCode(orderCode);
+        } else {
+            order = orderService.selectFsStoreOrderById(orderId);
+        }
+        if (order == null) {
+            return R.error("订单不存在");
+        }
+        R denied = denyIfNotCurrentUser(order.getUserId());
+        if (denied != null) {
+            return denied;
+        }
+        return orderService.getMyStoreOrderByIdOrOrderCode(order.getId(), orderCode);
     }
 
     @Login
@@ -85,6 +99,14 @@ public class StoreOrderController extends  AppBaseController {
     @GetMapping("/getStoreOrderById")
     public R getStoreOrderById(@RequestParam("orderId") Long orderId){
         logger.info("开始处理获取订单请求, 订单ID: {}", orderId);
+        FsStoreOrder order = orderService.selectFsStoreOrderById(orderId);
+        if (order == null) {
+            return R.error("订单不存在");
+        }
+        R denied = denyIfNotCurrentUser(order.getUserId());
+        if (denied != null) {
+            return denied;
+        }
         return orderService.getStoreOrderById(orderId);
     }
 
@@ -94,6 +116,16 @@ public class StoreOrderController extends  AppBaseController {
     public R getStoreOrderByIdRemote(@RequestParam(value = "orderId",required = false) Long orderId,
                                      @RequestParam(value = "payCode",required = false) String payCode){
         logger.info("获取订单-轮询获取信息, 订单ID: {}, payCode: {}", orderId,payCode);
+        if (orderId != null) {
+            FsStoreOrder order = orderService.selectFsStoreOrderById(orderId);
+            if (order == null) {
+                return R.error("订单不存在");
+            }
+            R denied = denyIfNotCurrentUser(order.getUserId());
+            if (denied != null) {
+                return denied;
+            }
+        }
         return orderService.getStoreOrderByOrderIdTz(orderId,payCode);
     }
 
@@ -134,6 +166,15 @@ public class StoreOrderController extends  AppBaseController {
         Long orderId = param.getOrderId();
         logger.info("开始处理支付请求, 订单号: {}, 支付类型: {}", orderId, param.getPayType());
 
+        FsStoreOrder order = orderService.selectFsStoreOrderById(orderId);
+        if (order == null) {
+            return R.error("订单不存在");
+        }
+        R denied = denyIfNotCurrentUser(order.getUserId());
+        if (denied != null) {
+            return denied;
+        }
+
         RLock lock = redissonClient.getLock("payment:lock:" + orderId);
         R result = null;
 
@@ -170,6 +211,14 @@ public class StoreOrderController extends  AppBaseController {
     @PostMapping("/cancelPay")
     public R cancelPay(@Validated @RequestBody FsStoreOrderPayParam param) {
         logger.info("用户取消支付 订单号: {},支付类型",param.getOrderId());
+        FsStoreOrder order = orderService.selectFsStoreOrderById(param.getOrderId());
+        if (order == null) {
+            return R.error("订单不存在");
+        }
+        R denied = denyIfNotCurrentUser(order.getUserId());
+        if (denied != null) {
+            return denied;
+        }
         orderService.cancelPay(param);
         return R.ok();
     }
@@ -180,6 +229,14 @@ public class StoreOrderController extends  AppBaseController {
     public R editPayType(@Validated @RequestBody FsStoreOrderPayParam param) {
         logger.info("开始处理修改支付类型请求, 参数: {}", param);
 
+        FsStoreOrder order = orderService.selectFsStoreOrderById(param.getOrderId());
+        if (order == null) {
+            return R.error("订单不存在");
+        }
+        R denied = denyIfNotCurrentUser(order.getUserId());
+        if (denied != null) {
+            return denied;
+        }
         return orderService.editPayType(param);
     }
 
@@ -190,6 +247,14 @@ public class StoreOrderController extends  AppBaseController {
     public R payRemain(@Validated @RequestBody FsStoreOrderPayParam param) {
         logger.info("开始处理支付尾款请求, 参数: {}", param);
 
+        FsStoreOrder order = orderService.selectFsStoreOrderById(param.getOrderId());
+        if (order == null) {
+            return R.error("订单不存在");
+        }
+        R denied = denyIfNotCurrentUser(order.getUserId());
+        if (denied != null) {
+            return denied;
+        }
         return orderService.payRemain(param);
     }
 
@@ -249,6 +314,10 @@ public class StoreOrderController extends  AppBaseController {
         if (ObjectUtil.isNull(order)) {
             throw new CustomException("订单不存在");
         }
+        R denied = denyIfNotCurrentUser(order.getUserId());
+        if (denied != null) {
+            return denied;
+        }
         if (order.getStatus() !=0) {
             throw new CustomException("非法操作");
         }
@@ -270,6 +339,10 @@ public class StoreOrderController extends  AppBaseController {
         if (ObjectUtil.isNull(order)) {
             throw new CustomException("订单不存在");
         }
+        R denied = denyIfNotCurrentUser(order.getUserId());
+        if (denied != null) {
+            return denied;
+        }
         if (order.getStatus() <2) {
             throw new CustomException("未发货订单不能查询");
         }
@@ -286,6 +359,10 @@ public class StoreOrderController extends  AppBaseController {
         if (ObjectUtil.isNull(order)) {
             throw new CustomException("订单不存在");
         }
+        R denied = denyIfNotCurrentUser(order.getUserId());
+        if (denied != null) {
+            return denied;
+        }
         if (order.getStatus() <2) {
             throw new CustomException("未发货订单不能查询");
         }
@@ -319,6 +396,14 @@ public class StoreOrderController extends  AppBaseController {
     @ApiOperation("完成订单")
     @PostMapping("/finishOrder")
     public R finishOrder( @Validated @RequestBody FsStoreOrderFinishParam param){
+        FsStoreOrder order = orderService.selectFsStoreOrderById(param.getOrderId());
+        if (order == null) {
+            return R.error("订单不存在");
+        }
+        R denied = denyIfNotCurrentUser(order.getUserId());
+        if (denied != null) {
+            return denied;
+        }
         return orderService.finishOrder(param.getOrderId());
     }