PT-2026-44439 · Packagist · Shopper/Cart
Publicado
2026-05-18
·
Atualizado
2026-05-18
CVSS v3.1
5.9
Média
| Vetor | AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N |
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::transactionwithlockForUpdateand a compare-and-swap ontotal use. - Throws
DiscountLimitReachedException::globaland rolls back the transaction when the global limit was exhausted between cart validation and commit. No order is committed. - Throws
DiscountLimitReachedException::perUserand 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 applyanddiscount currency codeonto theorderstable 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 migrateWorkarounds
None. Upgrade to
v2.8.0.Resources
- Issue: https://github.com/shopperlabs/shopper/issues/510
- Pull request: https://github.com/shopperlabs/shopper/pull/511
- CWE-362 Concurrent Execution using Shared Resource with Improper Synchronization
Correção
Race Condition
Encontrou algum problema na descrição? Tem algo a acrescentar? Fique à vontade para nos escrever 👾
Enumeração de Fraquezas
Identificadores relacionados
Produtos afetados
Shopper/Cart