A cached discount and a redirected payout
E-commerce
A marketplace connected buyers with independent merchants and paid merchants on a schedule. We were asked whether a discount could be made to apply where it should not, and whether a payout could be pointed at the wrong account.
Web & API penetration test, Online marketplace, severity HIGH, reported 2025
At a glance
- Challenge. A pricing cache did not key on every price input, and payout details could be changed without strong proof, notice or a hold.
- Approach. We varied the discount inputs and watched whether the cache key followed, then tested what proof and delay stood between a payout change and money moving.
- Result. The cache now keys on every price input, payout changes need strong re-authentication and trigger notice and a hold, and both flows were retested.
- Impact. An attacker could have received discounts computed for someone else and redirected a merchant's payouts to an account of their choosing before anyone noticed.
- Classification. CWE-1390 Weak Authentication, OWASP API Security Top 10 (2023): API2 Broken Authentication. Component: Pricing cache and merchant payout details.
The challenge
A cache exists to serve the same answer quickly. It becomes a flaw when the answer depends on who is asking and the cache does not. A discount computed for one context and then served from a cache to another context is a price decided for the wrong person, at machine speed and volume.
A payout destination is the most sensitive field a marketplace holds, because it is where money leaves. If the destination can be changed without proving the change came from the merchant, and without a delay or notice that lets a wrong change be caught, then updating a bank detail becomes a way to intercept earnings.
Both weaknesses hide inside ordinary features. A discount is meant to apply. A payout detail is meant to be editable. The failure is in the conditions under which each is allowed.
Our approach
We looked at what varied the discount and whether the cache key varied with it, and we examined the payout detail change to see what proof and what delay stood between a request and money moving.
Around those findings we checked the surface that shared the assumption:
- Whether cached responses keyed on every input that changed the price
- Whether payout changes required strong re-authentication
- Whether a change triggered notice and a hold before the next payout
- Whether the same caching pattern reached other user-specific responses
Delivered with the requests and responses observed, so each finding could be reproduced against a test merchant without taking our word for it.
From finding to fix
- Varied the discount and watched the cache
- Served a discount to the wrong context
- Changed a payout without strong proof
- Keyed the cache, gated payouts, retested
The outcome
Cached responses now key on every input that varies the price, so a discount is served only in the context it was computed for. Payout changes require strong re-authentication and trigger notice and a hold, so a redirected destination is caught before money moves.
We retested the pricing cache and the payout flow after the fix. Reported as HIGH in 2025. Retest included in the engagement.
Check your own system
- List every input that changes a price, such as the user, coupon or region, and confirm each one is part of the cache key.
- Send the same priced request from two different buyer contexts and compare the cached responses.
- Require fresh, strong re-authentication before any change to a payout destination is accepted.
- Notify the merchant through an existing channel and hold the next payout after a destination change, so a wrong change can be caught.
Read more case studies, see Web Application Penetration Testing, or write to hello@yaamlabs.com.