CVE-2026-47741 Overview
CVE-2026-47741 is a race condition vulnerability in Shopper, a headless e-commerce admin panel maintained by Shopperlabs. The flaw exists in the CreateOrderFromCartAction::execute method in versions prior to 2.8.0. The action created the Order row before checking and incrementing the discount's total_use counter. Under concurrent checkout load, the global usage_limit enforcement breaks. Attackers can redeem a single coupon beyond its configured limit by issuing parallel checkout requests. The vulnerability is tracked under [CWE-362] Concurrent Execution using Shared Resource with Improper Synchronization.
Critical Impact
Concurrent checkout requests bypass discount usage_limit enforcement, allowing over-redemption of coupons with no merchant signal that the limit was breached.
Affected Products
- Shopperlabs Shopper versions prior to 2.8.0
- Headless e-commerce deployments built on the Shopper admin panel
- Storefronts exposing the cart-to-order checkout flow during promotional events
Discovery Timeline
- 2026-05-29 - CVE-2026-47741 published to NVD
- 2026-05-29 - Last updated in NVD database
- Fix released in Shopper version 2.8.0 per GitHub Security Advisory GHSA-9rh9-hf3w-9fgg
Technical Details for CVE-2026-47741
Vulnerability Analysis
The vulnerability lives in CreateOrderFromCartAction::execute, the action responsible for converting a cart into a persisted order. The pre-2.8.0 implementation persists the Order row with the discount fully applied to price_amount before it validates and increments the discount's total_use counter against usage_limit. The check and the increment are not performed atomically inside a locked transaction. The committed Order is the side effect that customers care about and merchants account for in revenue. The counter update is a downstream bookkeeping step that can silently fail or block while the order remains valid.
Root Cause
The root cause is non-atomic check-then-act logic across two database operations [CWE-362]. The Order insert and the discount counter mutation are not serialized by row-level locking or an optimistic concurrency check. Two simultaneous checkouts both read total_use below usage_limit, both insert orders with the discount applied, and only one of them advances the counter to the limit. The remaining concurrent writers create over-limit redemptions that are never reflected in total_use.
Attack Vector
An attacker who possesses a valid promotional code submits multiple concurrent checkout requests through the storefront API. The required conditions are network access to the checkout endpoint, no authentication beyond a valid cart session, and timing close enough that requests race the counter check. Real-world traffic such as Black Friday, flash sales, or viral coupon distribution produces the same conditions organically without malicious intent. The result is financial loss through unbounded discount application while telemetry indicates the limit held.
No public exploit code is documented for this issue. Technical details are available in GitHub Issue #510 and GitHub Pull Request #511.
Detection Methods for CVE-2026-47741
Indicators of Compromise
- Orders whose discount_id matches a discount whose total_use equals usage_limit but where the count of orders referencing that discount exceeds total_use.
- Bursts of successful checkout requests sharing the same coupon code within a sub-second window from one or more clients.
- Promotional revenue reconciliation reports showing applied discount value greater than usage_limit * per_use_discount.
Detection Strategies
- Run a reconciliation query that joins the orders table to the discounts table and flags any discount where COUNT(orders) > total_use or COUNT(orders) > usage_limit.
- Instrument the checkout endpoint with per-coupon rate metrics and alert when concurrent in-flight requests for the same code exceed a defined threshold.
- Audit application logs for repeated CreateOrderFromCartAction invocations with identical discount identifiers within the same millisecond bucket.
Monitoring Recommendations
- Capture web access logs for the checkout route and forward them to a SIEM or data lake for correlation against discount usage tables.
- Track database transaction duration and lock wait events on the discount and orders tables to surface contention patterns.
- Establish a daily job that compares billed discount totals against configured usage_limit values and reports deviations.
How to Mitigate CVE-2026-47741
Immediate Actions Required
- Upgrade Shopper to version 2.8.0 or later, which serializes the discount check and counter increment inside the order creation transaction.
- Identify any active promotional codes and audit recent orders for over-redemption using the reconciliation query described above.
- Temporarily reduce usage_limit headroom or disable high-risk coupons until the patched version is deployed.
Patch Information
The fix is available in Shopper 2.8.0. The change reorders the operation so the discount row is locked, the total_use counter is checked and incremented, and the Order row is then created in the same transaction. Review the patch in GitHub Pull Request #511 and the coordinated disclosure in GHSA-9rh9-hf3w-9fgg.
Workarounds
- Wrap calls to CreateOrderFromCartAction::execute in an application-level mutex keyed by discount identifier until the upgrade is applied.
- Apply a database-level unique constraint or pessimistic lock (SELECT ... FOR UPDATE) on the discount row before order insertion.
- Throttle checkout requests per coupon code at the edge or API gateway to limit concurrent in-flight redemptions.
# Upgrade Shopper to the patched release
composer require shopperlabs/shopper:^2.8.0
php artisan migrate
php artisan config:clear
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


