June 4, 2026
From Quantity Manipulation to Negative Shipping Costs: A Business Logic Flaw in an E-Commerce…
One of the most dangerous assumptions in software development is believing that users will only interact with an application through the…
Hangga Aji Sayekti
5 min read
One of the most dangerous assumptions in software development is believing that users will only interact with an application through the user interface you've carefully designed.
Unfortunately, attackers don't care about your UI.
Recently, I was assessing the security of an online store that sells home security equipment. To respect responsible disclosure and maintain privacy, I will not mention the company's name.
Like many e-commerce websites, the store allowed customers to adjust product quantities using a familiar interface:
<button>-</button>
<input type="number" value="1">
<button>+</button><button>-</button>
<input type="number" value="1">
<button>+</button>Everything looked normal. The UI prevented negative values and restricted customers from entering extremely large numbers. At first glance, it seemed secure enough.
At least for normal users.
The Problem with Trusting the Frontend
As I progressed through the checkout flow, I started intercepting requests using Burp Suite. One habit I've developed over the years is trying inputs that developers never expect someone to send.
What happens if the quantity becomes 9999999?
The browser wouldn't allow it through the normal interface.
But browsers are not security controls.
So I modified the request manually.
The server accepted it.
No validation errors.
No rejection.
No complaints.
Nothing.
At this point, the application had already violated one of the most fundamental secure coding principles:
Never trust data coming from the client.
Not browsers.
Not mobile applications.
Not hidden fields.
Not JavaScript.
Nothing.
Things Got Weird
After modifying the quantity, I continued through the checkout process expecting a calculation error, a broken page, or perhaps an exception.
What I didn't expect was the shipping cost becoming negative.
Yes, negative.
Instead of increasing the total order cost, the shipping calculation started reducing it. The larger the quantity became, the more broken the pricing logic appeared.
Even more surprising, the application continued processing the order as if nothing unusual had happened. Moments later, I received a payment confirmation email.
At that point, this was no longer just an input validation issue.
It had become a business logic vulnerability.
The application was performing critical calculations using attacker-controlled values without properly validating them first.
The Secure Coding Lesson
What makes this finding interesting is that it wasn't caused by a sophisticated attack technique.
There was no zero-day vulnerability.
No complex exploitation chain.
No advanced bypass.
The root cause was something far simpler:
The server trusted user input.
Unfortunately, this is a mistake that development teams continue to repeat.
Many developers spend days or even weeks polishing frontend restrictions. They disable buttons, add JavaScript validation, configure minimum and maximum values, and use input type="number" fields. Once everything looks correct in the browser, they assume the problem has been solved.
It hasn't.
Not even close.
If your security depends on input type="number", congratulations — your application is protected by the same mechanism attackers bypass before finishing their first cup of coffee.
Attackers do not interact with your application the way you designed it.
They interact with it the way your server accepts it.
If the backend blindly trusts whatever comes from the client, every frontend restriction becomes nothing more than a visual suggestion.
That's not security.
That's decoration.
What Should Have Happened?
The server should independently validate every security-sensitive value received from the client.
For example:
- Is the quantity greater than zero?
- Is the quantity within an acceptable range?
- Does it exceed inventory limits?
- Can it trigger unexpected pricing calculations?
- Can it create integer overflows or calculation errors?
- Does the final order total remain logically valid?
Invalid requests should be rejected immediately, regardless of what the frontend allows or prevents.
A useful mindset is simple:
Treat every incoming request as potentially malicious.
Because sooner or later, one of them will be.
Security-sensitive decisions must always be enforced by the backend, where attackers have significantly less control.
A Message for Product Owners
This isn't just a developer problem.
It's also a product problem.
Many organizations prioritize new features, conversion rates, deadlines, and user experience while treating security validation as an optional enhancement.
Product owners often celebrate a successful checkout flow. Attackers celebrate the fact that nobody tested what happens when the quantity becomes 999999.
Security incidents are rarely caused by Hollywood-style hacking.
More often, they happen because basic assumptions were never questioned.
Every checkout flow, discount system, loyalty program, pricing engine, and shipping calculator is part of your attack surface. When validation is ignored, attackers don't need sophisticated techniques.
Sometimes all they need is a number your developers never expected anyone to enter.
Why This Matters
At first glance, a negative shipping cost might look like nothing more than a calculation bug.
But think about it from a business perspective.
Every value involved in a checkout process eventually affects money. Product prices, discounts, taxes, shipping fees, and final order totals all contribute to the amount a customer pays.
In this case, a user-controlled value was able to influence a critical pricing calculation. While I stopped testing after confirming the issue and responsibly reported it, a malicious actor might not be so considerate.
They would keep experimenting.
Trying different values.
Looking for ways to reduce costs even further.
The real concern isn't the negative shipping cost itself. The real concern is that the server trusted data it should never have trusted in the first place.
Many developers underestimate input validation flaws because they don't expose customer data or provide account access. However, vulnerabilities that affect business logic can be just as damaging.
After all, if an attacker can influence how your application calculates prices, discounts, or shipping fees, they're no longer just using your store.
They're helping decide what your products should cost.
Final Thoughts
This finding serves as a reminder that some of the most impactful vulnerabilities originate from the simplest mistakes.
The quantity field looked harmless.
The checkout page looked polished.
The user interface appeared well controlled.
Yet a single modified parameter was enough to break critical business logic and produce negative shipping costs.
The browser enforced the rules.
The server didn't.
And in security, the only rules that matter are the ones enforced by the server.
The lesson is simple:
Validate on the server. Always.
Validate on the server. Always. The frontend exists for convenience. The backend exists for trust.
Confusing those two responsibilities is how vulnerabilities are born.