Skip to content

Commit a7d365c

Browse files
committed
Rate limit couponCode updates
1 parent 57d90a8 commit a7d365c

2 files changed

Lines changed: 15 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Release Notes for Craft Commerce
22

3+
## Unreleased
4+
5+
- Cart requests that include a `couponCode` param are now rate-limited. (GHSA-h5gm-x9wr-vhcm)
6+
37
## 4.11.1 - 2026-04-30
48

59
- PDF download tokens now use Craft’s native token expiry.

src/controllers/CartController.php

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@
4040
*/
4141
class CartController extends BaseFrontEndController
4242
{
43+
/**
44+
* Params that trigger IP-based rate limiting on cart actions.
45+
*/
46+
public const RATE_LIMITED_PARAMS = ['number', 'couponCode'];
47+
4348
/**
4449
* @var Order The cart element
4550
*/
@@ -87,14 +92,16 @@ public function behaviors()
8792
'only' => ['get-cart', 'update-cart', 'load-cart', 'complete'],
8893
'enableRateLimitHeaders' => false,
8994
'user' => function() {
90-
// Only apply rate limiting when a cart number is explicitly passed
91-
$isActive = Craft::$app->getRequest()->getBodyParam('number') || Craft::$app->getRequest()->getQueryParam('number');
95+
// Only apply rate limiting when a cart number or coupon code is explicitly passed
96+
$request = Craft::$app->getRequest();
97+
$isActive = collect(self::RATE_LIMITED_PARAMS)
98+
->contains(fn($param) => $request->getBodyParam($param) || $request->getQueryParam($param));
9299

93100
return $isActive ? new IpRateLimitIdentity([
94101
'limit' => 1,
95102
'window' => 1,
96-
'keyPrefix' => 'cart-number-rate-limit',
97-
'ip' => Craft::$app->getRequest()->getUserIP() ?? 'unknown',
103+
'keyPrefix' => 'cart-rate-limit',
104+
'ip' => $request->getUserIP() ?? 'unknown',
98105
]) : null;
99106
},
100107

0 commit comments

Comments
 (0)