Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessIdentify active coupon code with usage_limit configured
-
DeliverySubmit concurrent checkout requests applying coupon code
-
ExploitMultiple requests simultaneously read pre-limit total_use value
-
ExecutionAll pass validation before any counter increment is written
-
PersistOrders committed to database with full discount applied to price_amount
-
ImpactCounter reaches usage_limit after over-commitment - merchant absorbs unintended financial loss with no alert
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A06:2025 - Insecure Design
ASVS 5.0
V15 - Secure Coding and Architecture Concurrency control, locking
MITRE ATT&CK
1 technique across 1 tactic: Privilege Escalation The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up. |
| Exploitation Conditions | Exploitation of the global limit bypass requires at least one active discount code configured with a non-zero usage_limit in the target Shopper installation, and the ability to submit multiple simultaneous checkout requests applying that code - achievable with a scripted HTTP client, coordinated browser tabs, or simply by sharing a coupon publicly during a high-traffic event. No authentication is required per CVSS PR:N, as the checkout flow is customer-facing. The race window is narrow per request pair, making reliable single-attacker exploitation difficult at low request volume, but the concurrency threshold is inherently met during promotional events the merchant deliberately drives. Exploitation of the per-user limit bypass (usage_limit_per_user) requires only that the discount be configured with a per-user cap - no concurrency is needed, as the underlying DiscountDetail.total_use counter was never incremented in any code path, making every redemption appear as the customer's first regardless of history. For discounts with eligibility=Everyone, the per-user check cannot fire at all because no DiscountDetail row exists for that eligibility mode. Limiting factors for the global race: attack complexity is genuinely high at low traffic volumes; exploitation becomes reliable only when merchant-driven promotional load creates natural concurrency. |
| Impact | CVSS 5.9 (AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N) accurately classifies the network-accessible, unauthenticated attack surface with an Integrity:High impact reflecting unauthorized financial manipulation. The AC:H designation acknowledges the race window that must be won, but this rating can be misleading in practice: during promotional events that generate natural high-concurrency checkout traffic, the race becomes statistically reliable without any attacker-controlled infrastructure. No EPSS score was provided in the input data. The CVE is not in CISA KEV, and no public POC exploit code has been identified, indicating no confirmed active exploitation at time of analysis. Real-world financial risk is elevated for merchants running time-limited promotional campaigns - the exact traffic conditions that make exploitation reliable are also the conditions merchants deliberately create. The secondary per-user limit bug means that merchants who believed they had per-user caps as a safety net were entirely unprotected, compounding the integrity impact beyond what the global limit alone suggests. CVSS Confidentiality:N is confirmed - no data exfiltration vector is present. The 'Information Disclosure' tag in the source metadata appears to be a classification error inconsistent with both the description and the CVSS vector. |
| Exploit ScenarioDerived | During a flash sale, an attacker distributes a limited-use coupon code or identifies one through normal shopping activity, then scripts dozens of simultaneous POST requests to the checkout endpoint - all applying the same coupon at the moment total_use approaches usage_limit. Because pre-2.8.0 Shopper reads total_use, validates, inserts the Order row, and only then increments the counter without database locking, multiple concurrent requests observe the same below-limit counter value, pass validation independently, and are all committed with the full discount applied. The merchant's usage_limit counter eventually reaches its ceiling, but significantly more orders than intended have already been stored with discounted price_amount values, representing direct and silent financial loss with no alert generated. No public POC exploit code has been identified at time of analysis. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – May 29, 2026
Discount over-redemption via race condition in Shopper (shopperlabs/shopper prior to v2.8.0) allows concurrent unauthenticated checkout requests to bypass a coupon's global usage_limit, resulting in committed orders carrying unauthorized discounts the merchant never intended to grant. The CreateOrderFromCartAction::execute method created the Order database row before atomically reserving the discount slot, opening a classic TOCTOU window that becomes reliably exploitable under the high-concurrency traffic of flash sales or Black Friday events. A compounding bug rendered usage_limit_per_user entirely non-functional in all pre-2.8.0 versions - the underlying counter was never incremented anywhere in the codebase - meaning per-user caps provided zero protection regardless of a customer's redemption history. No public exploit identified at time of analysis; this CVE is not listed in CISA KEV.
RemediationAI
Upgrade both shopper/cart and shopper/core to version 2.8.0 by running 'composer require shopper/cart:^2.8 shopper/core:^2.8' followed by 'php artisan migrate' - the migration step is required to apply schema changes that snapshot discount metadata (discount_id, discount_code, discount_type, discount_value_at_apply, discount_currency_code) onto the orders table for audit resilience. The fix is confirmed in PR #511 (commit fcd0c5920588702df5b874f432b1042abd77a50b) and detailed in the vendor advisory at https://github.com/shopperlabs/shopper/security/advisories/GHSA-9rh9-hf3w-9fgg. The vendor explicitly states no workarounds exist. As an emergency compensating control prior to upgrading, operators can disable all discount codes with usage limits entirely, eliminating the financial exposure at the cost of all promotional functionality. Setting artificially low usage_limit values does not prevent the race condition but limits the magnitude of over-redemption per campaign. Neither compensating control addresses the per-user limit bug, which requires the v2.8.0 code fix.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 2 packages in composer, euvd
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
The vulnerability exists in the shopperlabs/shopper PHP Composer packages (shopper/cart and shopper/core), a Laravel-based headless e-commerce admin panel (CPE: cpe:2.3:a:shopperlabs:shopper:*:*:*:*:*:*:*:*). The root cause maps precisely to CWE-362 (Concurrent Execution using Shared Resource with Improper Synchronization). The CreateOrderFromCartAction::execute method performed a non-atomic check-then-act sequence: it read the discount's total_use value, validated it against usage_limit, committed the Order row to the database, and only then incremented total_use - without holding a database lock across these operations. This creates a TOCTOU window where multiple concurrent HTTP requests can simultaneously read the same pre-limit total_use value, all pass validation independently, and all commit orders with the discount applied before any counter increment is written. The fix in v2.8.0 wraps the entire sequence inside a DB::transaction using lockForUpdate with a compare-and-swap on total_use, making the reservation atomic and rolling back with DiscountLimitReachedException if the limit was exhausted between cart validation and commit. The secondary defect - DiscountDetail.total_use never being incremented - meant the per-user check perpetually observed 0 prior uses; for eligibility=Everyone discounts, the requisite DiscountDetail row did not even exist, making the per-user path entirely unreachable.
Know when Shopper gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N
Primary rating from Vendor (GitHub_M) · only source for this CVE.
CVSS VectorVendor: GitHub_M
Lifecycle Timeline
1DescriptionCVE.org
Shopper is a Headless e-commerce Admin Panel. Prior to 2.8.0, CreateOrderFromCartAction::execute previously created the Order row before checking and incrementing the discount's total_use counter. Under concurrent checkout pressure (Black Friday, flash sale, viral coupon), the global usage_limit was silently exceeded: orders were committed with the discount fully applied to price_amount while the counter blocked at usage_limit. The merchant had no signal that an over-redemption had occurred. This vulnerability is fixed in 2.8.0.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Information disclosure occurs when an application unintentionally exposes sensitive data that aids attackers in reconnaissance or directly compromises security.
Race conditions occur when multiple concurrent requests exploit the brief time gap between checking a condition and acting upon it (TOCTOU - Time of Check, Time of Use).
Privilege escalation in Shopper headless e-commerce admin panel prior to version 2.8.0 allows any low-privilege authenti
Privilege escalation in Shopper 2.0.0 through 2.5.x allows an authenticated admin-panel user who holds only the access_d
Stored cross-site scripting in the Shopper headless e-commerce admin panel (2.0.0 up to but not including 2.10.1, plus 3
Authorization bypass in Shopperlabs Shopper headless e-commerce admin panel prior to 2.8.0 allows authenticated low-priv
Permanent deletion of product variants in Shopper's admin panel is possible for any authenticated staff member who holds
Privilege escalation in shopperlabs/shopper prior to 2.8.0 allows any authenticated admin panel user - regardless of ass
Missing authorization enforcement in the Shopper headless e-commerce admin panel (all versions prior to 2.8.0) allows an
Shopper versions prior to 2.10.1 expose administrator and staff profile records to low-privileged admin-panel users thro
EUVD-2026-33409
NVD
CVE.org
EPSS
Vulnrichment
GitHub
Exploit-DB