While testing an e-commerce API during a security assessment, I discovered a **business logic vulnerability** that allowed bypassing purchase limits for restricted products.
Many online stores apply quantity restrictions to prevent customers from purchasing large amounts of discounted or limited-stock products. These limits are intended to maintain fairness and protect promotional inventory.
However, by manipulating a request sent to the cart API, it was possible to **add unlimited quantities of a restricted product**, bypassing both frontend and backend protections.
---
## The Intended Protection
The application enforces quantity limits for certain products. Normally:
1. A user adds a restricted item to the cart. 2. The interface prevents increasing the quantity beyond the allowed limit. 3. Attempts to increase the quantity further may trigger server-side validation errors.
This creates the assumption that the restriction is enforced securely.
---
## Initial Observation
When testing the API responsible for updating the cart, the request contained a JSON structure representing cart items.
Example structure:
``` { "lines": [ { "id": "ITEM_ID", "product_sku": "SKU_ID", "quantity": 2, "isMaxDiscountedReached": false } ] } ```

The API allows multiple entries inside the `lines` array.
This raised an interesting question:
> What happens if the same product is added multiple times inside the same request?
---
## Failed Attempts
Before discovering the working method, several attempts were made to bypass the restriction.
### Attempt 1: Increasing Quantity Directly
The most obvious approach was to simply modify the `quantity` value in the request.
Example:
``` { "lines": [ { "id": "ITEM_ID", "product_sku": "SKU_ID", "quantity": 10, "isMaxDiscountedReached": false } ] } ```
However, the server responded with an error and rejected the request.
In some cases, the application returned a **500 Internal Server Error**, suggesting that the backend detected an invalid quantity.
---
### Attempt 2: Race Condition
Another approach was attempting a **race condition attack** by sending multiple requests simultaneously to increase the cart quantity.
The idea was that concurrent requests might bypass validation before the limit was enforced.
However, this attempt failed because the backend handled concurrent updates correctly and maintained the quantity restriction.
---
## Exploiting the Logic Flaw
Instead of increasing the quantity value, the same product entry can be **duplicated multiple times in the payload**.
Modified request:
``` PUT /consumer-backend/cart/v3/cart/{cart_id} HTTP/2 Authorization: Bearer <token> Content-Type: application/json
{ "lines": [ { "id": "ITEM_ID", "product_sku": "SKU_ID", "quantity": 2, "isMaxDiscountedReached": false }, { "id": "ITEM_ID", "product_sku": "SKU_ID", "quantity": 2, "isMaxDiscountedReached": false } ] } ```
Instead of validating duplicates, the backend **sums the quantities**, resulting in:
``` Cart total = 4items ```
The server treats each line as a separate entry and aggregates them.

---
## Why the Protection Failed
The vulnerability exists because the backend validates **individual line items** rather than **total quantities per product**.
Instead of enforcing:
``` Total quantity of SKU <= Allowed limit ```
the application only processes each entry independently.
This creates a classic **business logic flaw**, where the application behaves correctly from a technical perspective but fails to enforce the intended business rule.
---
## Root Cause
The backend does not properly validate duplicate product entries in the request payload.
Instead of verifying the **total quantity of each product SKU**, the system simply aggregates entries after processing them individually.
---
## Remediation
To prevent this issue, the backend should implement strict validation rules:
### 1. Aggregate Quantity Validation
Before processing the cart update:
``` Total quantity per SKU <= Maximum allowed ```
### 2. Reject Duplicate Line Entries
If the same product appears multiple times in the payload:
``` Return validation error ```
### 3. Server-Side Enforcement
Do not rely on frontend controls to enforce purchase limits.
All restrictions must be validated **server-side**.
