Business Logic Vulnerabilities: What Scanners Can't Find
There's a class of vulnerability that doesn't have a CVE number. It doesn't match a signature. No automated tool will flag it. The HTTP requests involved are syntactically perfect — valid endpoints, valid parameters, valid authentication tokens. Everything about the request looks legitimate.
Because it is legitimate. The attacker is using the application exactly as it was designed to be used. They're just using it in a way the developers never anticipated.
These are business logic vulnerabilities, and they are among the most impactful and most frequently overlooked security flaws in modern applications.
Why Business Logic Flaws Are Different
Most vulnerability classes involve sending something the application shouldn't accept — a SQL injection payload in a search field, a script tag in a form input, a malformed header that triggers a buffer overflow. The application's failure is in how it handles unexpected input.
Business logic vulnerabilities are the opposite. The input is expected. The endpoint is correct. The authentication is valid. The flaw is in what the application allows a legitimate user to do when they use features in sequences, combinations, or contexts the designers didn't consider.
This distinction is important because it explains why automated scanning tools — no matter how sophisticated — fundamentally cannot detect these flaws. A scanner can test whether an input field is vulnerable to injection. It cannot test whether your checkout workflow allows a user to apply a percentage discount after a fixed discount, resulting in a negative total. It doesn't know your business rules, so it can't identify when they're violated.
In our experience across 400+ assessed targets, business logic flaws account for some of the highest-severity findings — and they're almost never caught by prior automated testing.
Common Business Logic Vulnerability Patterns
Price and Quantity Manipulation
E-commerce and SaaS platforms process financial transactions, and any gap between what the client sends and what the server enforces is exploitable.
Client-side price reliance. Some applications pass the price from the client to the server during checkout. The product page shows $99.99, and the checkout request includes "price": 99.99 as a parameter. Changing it to "price": 0.01 before submission — if the server doesn't validate against its own price database — results in a legitimate-looking order at an attacker-controlled price.
Negative quantity exploitation. Adding -1 of an item to a cart, where the application calculates the total as quantity * price, can produce a negative line item that reduces the order total. We've seen cases where adding a high-value item at quantity 1, then adding a low-value item at quantity -10, resulted in the order total dropping below zero — which the payment processor accepted as a zero-charge transaction.
Currency and rounding abuse. Applications that handle multiple currencies, apply percentage discounts, or calculate taxes with rounding can be exploited through precision manipulation. Repeated small transactions that accumulate rounding errors in the attacker's favor follow the same pattern as classic salami-slicing attacks.
Coupon and Discount Stacking
Promotional systems are rich targets for logic abuse:
Multiple application of single-use codes. A coupon marked as "single use" is applied during checkout. But what if the user opens two browser tabs, adds the coupon in both, and submits both checkouts simultaneously? If the application checks whether the coupon has been used before applying it — but the check and the application aren't atomic — both requests pass the check before either marks the coupon as used.
Stacking incompatible discounts. A 20% loyalty discount and a 30% promotional code might each be valid individually. The UI prevents applying both. But the API endpoint that applies discounts doesn't enforce mutual exclusivity — it just applies whatever discount code it receives. Sending both in the same request, or applying one after the other through direct API calls, produces a 50% discount that was never intended.
Referral and reward abuse. Referral programs that credit both the referrer and the referred user can be exploited through self-referral loops. Creating multiple accounts, referring yourself, collecting the bonuses, and funneling the value to a single account. If the application only checks email uniqueness but not device fingerprinting, IP correlation, or payment method association, the abuse scales trivially.
Race Conditions
Race conditions occur when the outcome of an operation depends on the timing of concurrent events, and the application doesn't handle concurrency correctly.
Double-spending. A user has a $100 account balance. They simultaneously send two requests to purchase a $75 item. Both requests read the balance ($100), both confirm it's sufficient, both process the purchase, and both deduct $75. The user now has two items and a -$50 balance — or, more commonly, a $25 balance because only the last write persists.
Duplicate redemption. A one-time-use voucher is redeemed by sending concurrent requests. The first request checks if the voucher is valid (it is) and begins processing. Before it marks the voucher as used, the second request also checks validity (still valid, because the first hasn't finished) and also begins processing. Both succeed.
Limit bypass. An application limits each user to one free trial. The trial activation endpoint checks whether the user has already activated a trial. Two simultaneous requests both pass the check before either creates the trial record. The user ends up with two — or, with enough concurrent requests, as many as they want.
Race conditions are particularly dangerous in financial applications. We test for them in every engagement involving transactions, balance operations, or resource allocation.
Workflow Bypass
Multi-step processes — checkout flows, application submissions, account verification — assume users will complete steps in order. Business logic vulnerabilities arise when the application doesn't enforce that ordering server-side.
Skipping payment. A checkout flow has four steps: cart review, shipping address, payment, and confirmation. The application generates an order ID at step 1 and expects it to flow through all four steps. But if the confirmation endpoint at step 4 only checks for a valid order ID and doesn't verify that payment was completed at step 3, an attacker can jump from step 2 directly to step 4 — confirming the order without paying.
Bypassing verification. An account registration requires email verification before the account is fully activated. But the API that creates the account and the API that marks it as verified are separate endpoints. If the verification endpoint only checks for a valid token format (not whether the token was actually sent to the user's email), attackers can call it directly and skip verification entirely.
Reversing completed actions. Some applications allow modifications to records that should be immutable after a certain state transition. Changing a shipping address after an order has been dispatched, modifying a bid after an auction has closed, or editing an application after it's been submitted for review. If the application only checks state on the read path (displaying an "edit" button) but not on the write path (processing the edit request), the modification succeeds.
Feature Abuse and Rate Limit Bypass
Password reset flooding. The forgot password function sends an email to the specified address. There's no rate limit, or the rate limit is per-IP rather than per-account. An attacker triggers thousands of password reset emails to a victim's inbox, causing denial of service through inbox flooding and potentially burying legitimate emails.
API abuse for data harvesting. A search endpoint returns user information for valid queries. The application rate-limits the search page, but the underlying API endpoint isn't rate-limited. Scripted requests to the API enumerate the entire user database, one query at a time.
Free tier abuse. A platform offers limited functionality for free accounts and charges for premium features. But the premium features are only gated by the UI — the API endpoints that power them don't check the user's subscription tier. A free-tier user who calls the API directly accesses premium functionality without paying.
Why Manual Testing Is Non-Negotiable
Every pattern described above shares a characteristic: the attack uses legitimate application functionality in an unintended way. There's no payload to detect, no signature to match, no anomaly to flag.
Finding business logic vulnerabilities requires:
Understanding the application. A tester must understand what the application does, who its users are, what workflows exist, and what business rules should govern them. This requires reading documentation, exploring the application, and sometimes interviewing stakeholders.
Mapping assumptions. Every application makes implicit assumptions: users will complete steps in order, prices come from the server, coupons are used once, account balances can't go negative. The tester's job is to identify these assumptions and test each one.
Creative abuse. What happens if a field intended for quantities receives a negative number? What happens if two requests arrive simultaneously? What happens if step 3 is skipped? What happens if a parameter from one workflow is injected into another? This isn't following a checklist — it's adversarial thinking applied to business processes.
Contextual understanding. A 10% discount applied twice might be a minor financial issue for a low-value product but a critical vulnerability for a high-value financial platform. The severity depends on the business context, not the technical mechanism.
This is why business logic testing consistently produces findings that years of automated scanning missed. Across our 1,400+ documented findings, some of the most critical attack chains involved no traditional vulnerabilities at all — just sequences of legitimate actions that produced unauthorized outcomes.
Prevention Strategies
State Machine Validation
Model multi-step workflows as explicit state machines. Each step transitions the process from one defined state to another, and each transition has preconditions that must be met. The server validates the current state before allowing any transition.
For a checkout flow, this means the order object has a state field that progresses through cart -> address_provided -> payment_complete -> confirmed. The confirmation endpoint checks that the state is payment_complete before transitioning to confirmed. Skipping a step is impossible because the state value won't match.
Server-Side Enforcement of All Business Rules
Every business rule that matters must be enforced server-side, regardless of whether it's also enforced in the UI. This includes:
- Price calculations computed from server-side data, never from client-submitted values
- Discount and coupon rules validated at the time of order processing
- Quantity constraints checked against server-defined limits
- Workflow ordering enforced through state validation
- Rate limits applied at the application layer, not just the UI layer
If the rule only exists in JavaScript running in the browser, it doesn't exist.
Concurrency Controls
Protect operations that involve shared resources with appropriate concurrency controls:
- Database-level locking for balance operations — use SELECT FOR UPDATE or equivalent to prevent concurrent reads of stale data
- Atomic operations for check-and-update patterns — the check and the update must happen in the same transaction
- Idempotency keys for payment and redemption endpoints — the same request submitted twice produces the same result, not a duplicate operation
- Optimistic locking with version fields — updates that reference stale data are rejected
Input Validation Beyond Syntax
Validate inputs not just for type and format but for business sense. Quantities should be positive integers. Prices should match the product catalog. Discount percentages should fall within configured ranges. Dates should be logically consistent (end date after start date, appointment in the future).
Comprehensive Logging and Monitoring
Log business-significant events and monitor for anomalies: unusual discount application patterns, accounts with abnormally high referral counts, orders with zero or negative totals, multiple simultaneous requests from the same session. These patterns indicate either bugs or active exploitation.
Regular Manual Security Review
Business logic changes with every feature release. A new promotion system, a modified checkout flow, a redesigned account management process — each introduces new logic that could contain exploitable flaws. Regular manual security assessment ensures that new functionality is tested against the same adversarial thinking that attackers will apply.
The Cost of Ignoring Business Logic
Business logic vulnerabilities often have direct financial impact. Unlike an XSS vulnerability that requires social engineering to exploit, a price manipulation flaw can be exploited silently, repeatedly, and at scale. A race condition in a payment system can drain account balances. A workflow bypass can result in services delivered without payment.
These vulnerabilities don't appear in automated scan reports. They don't trigger alerts. They don't match signatures. They exist in the gap between what the application was designed to do and what it actually allows — and the only way to find them is to look.
Need your application tested for business logic flaws? Get in touch.