Executive brief
A race condition in the Shopper e-commerce framework allows customers to bypass discount usage limits during high-traffic events like flash sales. This can lead to significant financial loss as more discounts are applied than intended, and merchants receive no notification that limits were exceeded. Additionally, a bug in the per-user limit check allowed customers to reuse the same coupon indefinitely.
Technical details
The vulnerability consists of two primary issues within the Shopper framework. First, a race condition (CWE-362) exists in `CreateOrderFromCartAction::execute` because the order row was created before checking and incrementing the discount's `total_use` counter. Under high concurrency, multiple requests could pass the limit check before any single request updated the counter. Second, the `usage_limit_per_user` check was non-functional because the `DiscountDetail.total_use` counter was never incremented in the codebase. Attackers can exploit these by sending concurrent checkout requests or reusing coupons. The fix in v2.8.0 introduces atomic reservation using `lockForUpdate` and compare-and-swap operations within a database transaction.
Affected products
- shopperlabs shopper/cart < 2.8.0
- shopperlabs shopper/framework < 2.8.0
Timeline
- 2026-05-11: disclosed
- 2026-05-18: advisory
- 2026-05-18: patched