Application & API Security • 3 min read
Business Logic Vulnerabilities: How They Work and How to Prevent Them
Why flaws in workflow rules evade scanners and firewalls, with concrete examples (price tampering, coupon races, step skipping) and server-side patterns that prevent them.
By CryptoAgile Labs Editorial Team • Published August 2026 • Last updated October 10, 2026
A business logic vulnerability (BLV) is a flaw in the rules of an application rather than in how its code handles memory or input syntax. Every request is well-formed and every component works as designed. The attacker simply uses legitimate features in a sequence or with values the designers did not anticipate. Because nothing looks malformed, web application firewalls and generic scanners rarely notice.
Four classic examples
Price and quantity tampering. A checkout form sends {"item": 42, "price": 19.99, "qty": 1} and the server trusts the price. An attacker changes it to 0.01. A softer variant: the server accepts qty: -3, producing a negative total that credits the account.
Step skipping. A signup flow has steps: enter email, verify email, choose plan, pay. The "download" endpoint only checks that the user is logged in. By calling the final URL directly, the user skips verification and payment.
Race conditions. A single-use coupon is checked, then marked used. Two concurrent requests both pass the check before either marks it used, so the coupon applies twice. The same pattern affects withdrawals, inventory and rate limits. This is a time-of-check to time-of-use (TOCTOU) problem.
Abuse of legitimate features. A referral program pays rewards for signups, so an attacker scripts thousands of accounts. A "reset" feature enumerates which emails are registered. Each endpoint works as intended; the abuse is the vulnerability. OWASP's API list calls this unrestricted access to sensitive business flows.
Why scanners miss them
Detecting a BLV requires knowing what the application is supposed to do. A scanner can tell that a parameter is reflected unescaped; it cannot tell that a 90% discount is wrong. Defenses therefore depend on design discipline and tests that encode business rules, not signature matching.
Prevention patterns
1. Never trust client-supplied business values
Compute prices, totals, roles and permissions on the server from authoritative data. The client sends identifiers and quantities; the server looks up the price.
// Safe: price comes from the database, quantity is validated
const qty = Number.parseInt(req.body.qty, 10);
if (!Number.isInteger(qty) || qty < 1 || qty > 10) return res.status(400).end();
const item = await db.items.get(req.body.itemId);
const total = item.priceCents * qty;2. Enforce workflow state on the server
Model multi-step processes as a state machine stored server-side. Each endpoint verifies the current state allows the transition.
const ALLOWED = { created: ['verified'], verified: ['paid'], paid: ['active'] };
function transition(order, next) {
if (!ALLOWED[order.state]?.includes(next)) throw new Error('Invalid transition');
order.state = next;
}3. Make check-and-update atomic
Never read a value, decide, then write it back in separate steps. Push the condition into the write itself.
-- Redeem a coupon exactly once, even under concurrency
UPDATE coupons SET redeemed_at = now()
WHERE code = $1 AND redeemed_at IS NULL;
-- If rows affected = 0, the coupon was already usedIn DynamoDB use a conditional write (attribute_not_exists(redeemed_at)); in other stores use transactions or locks. Add idempotency keys for payment-like operations so retries do not duplicate effects.
4. Authorize every object access
Check that the authenticated user owns or may access the specific record, on every request. This closes the broken object-level authorization class in the API Security Top 10 guide.
5. Rate-limit and monitor flows, not just endpoints
Limits per account, device and IP on sensitive flows (signup, password reset, coupon redemption, checkout). Alert on abnormal sequences such as many accounts created from one source or repeated failed redemptions.
Finding them: threat modeling and tests
Before building a feature, list its assets, actors and the rules that must always hold ("a user can only pay once per order," "an item's price never goes negative"). Turn each rule into an automated test that tries to violate it: negative numbers, repeated requests, out-of-order calls and concurrent requests. These abuse-case tests catch more logic flaws than any scanner, and they keep catching them as the code changes.
Code review checklists help as well: for each endpoint ask, "What state must exist for this to be valid? What happens if I call it twice, in parallel, or out of order?"
Summary
Business logic flaws arise from unstated assumptions. Make the assumptions explicit, enforce them on the server, make critical updates atomic, and test the rules by trying to break them.
Sources and further reading
Related articles
This article is for educational purposes and is not professional security, legal or compliance advice. Spotted an error or an out-of-date detail? Email us a correction. See our editorial policy.