Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🐘
🐘 Packagist
Not in CISA KEV
MEDIUM severity

GHSA-9rh9-hf3w-9fgg

MEDIUMFix: shopperlabs/shopper#511

GHSA-9rh9-hf3w-9fgg is a medium-severity (CVSS 5.9) CWE-362 vulnerability in shopper/cart. O3 Security confirms whether GHSA-9rh9-hf3w-9fgg is actually reachable in your code before you act, and blocks exploitation at runtime until you patch.

shopper/framework: Race condition on Discount.usage_limit allows silent over-redemption

Also known asCVE-2026-47741
Published
May 18, 2026
Updated
Jun 8, 2026
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Aug 14, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.

Exploitation and automatability from CISA’s SSVC triage for GHSA-9rh9-hf3w-9fgg.

EPSS Exploitation Probability

via FIRST.org ↗
0.2%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs15th percentile — riskier than 15% of all scored CVEsHighest risk
0.00%0.25%0.49%0.74%0.0%0.2%0.2%0.2%Jun 26Aug 26Aug 26

EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.

How urgent is this, really

GHSA-9rh9-hf3w-9fgg plotted by exploitation likelihood (EPSS) against impact (CVSS). The shaded corner — EPSS 50%+ and CVSS 7.0+ — is where this CVE doesn't sit, though severity or exploitability alone can still warrant action.

Where this sits among everything scored

Of 0 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Real counts from FIRST.org, not a sample — log-scaled since the landscape is heavily right-skewed.

Real-World Exposure

1 pkg affected
🐘shopper/cart

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects Packagist packages — download data is not available via public APIs for these ecosystems.

Description

Impact

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.

A second related bug: usage_limit_per_user was effectively a no-op because the counter it relied on (DiscountDetail.total_use) was never incremented anywhere in the codebase. The per-user check therefore always saw 0 uses and validation passed regardless of how many times the same customer had previously redeemed the coupon. For eligibility = Everyone the per-user limit could not fire at all because the underlying DiscountDetail row only exists for eligibility = Customers.

Direct financial loss: each over-redemption is a discount the merchant did not intend to grant.

Patches

Fixed in v2.8.0. CreateOrderFromCartAction now:

  • Reserves the discount slot atomically before the order row is created, inside the same DB::transaction with lockForUpdate and a compare-and-swap on total_use.
  • Throws DiscountLimitReachedException::global and rolls back the transaction when the global limit was exhausted between cart validation and commit. No order is committed.
  • Throws DiscountLimitReachedException::perUser and rolls back when the discount is restricted to one use per customer and the customer has already redeemed it.
  • Snapshots discount_id, discount_code, discount_type, discount_value_at_apply and discount_currency_code onto the orders table for resilience against later discount edits or deletions.

DiscountValidator was updated to perform the same Order-based per-user check at cart-apply time so the rejection is surfaced before checkout.

Upgrade via:

composer require shopper/cart:^2.8 shopper/core:^2.8 php artisan migrate

Workarounds

None. Upgrade to v2.8.0.

Resources

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐘Packagistshopper/cartall versions2.8.0

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for shopper/cart. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.

  2. Fix

    Update shopper/cart to 2.8.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-9rh9-hf3w-9fgg is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 pinpoints whether GHSA-9rh9-hf3w-9fgg is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.

Tailored to GHSA-9rh9-hf3w-9fgg. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Frequently Asked Questions

## Impact `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. A second related bug: `usage_limit_per_user` was effectively a no-op because the counter it relied on (`DiscountDetail.total_use`) was never
O3 Security · Impact-Aware SCA

Is GHSA-9rh9-hf3w-9fgg in your dependencies?

O3 detects GHSA-9rh9-hf3w-9fgg across Packagist dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.