This article is a detailed guide to finding and reporting business logic vulnerabilities in e-commerce and SaaS applications as part of a bug bounty program. It explains why automated scanners cannot detect these flaws, teaches the methodology for identifying them through careful workflow mapping and parameter testing, and provides concrete techniques for safely demonstrating price manipulation, coupon abuse, workflow bypass, and boundary condition exploits. The article matters because business logic vulnerabilities often have directly quantifiable financial impact, making them high-priority findings that program managers understand immediately.
- Business logic flaws vs. input validationThe article distinguishes business logic vulnerabilities from traditional input validation issues: a price of 0.01 is syntactically valid (passes input validation) but violates the business rule that it should equal the catalog price. The weakness appears when the server accepts a value or sequence of actions that violates the application's own rules, not when input is malformed. Automated scanners cannot detect these because they have no model of what the application is 'supposed' to do—they know that SQL injection is unexpected input, but cannot determine that price=0.01 is unexpected in a c
- Workflow mapping as prerequisiteBefore testing any parameter, the article requires testers to map the entire application flow by intercepting normal requests in Burp Proxy and documenting which requests change state, what parameters influence business decisions, and what state changes should result. This mapping captures which values should be client-controlled versus server-derived (e.g., product_id and quantity are client input, but price should be looked up server-side), identifies dependencies between steps, and prevents blind request replaying. The flow notebook records action, endpoint, important parameters, expected s
- Price manipulation through parameter tamperingThe article demonstrates price manipulation by modifying checkout requests: changing a legitimate price like 299.99 to 0.01, testing negative prices to apply as credits, adding items at price=0, and observing whether the server calculates totals using client-supplied values or server-side catalog data. The secure design is for the client to send only product identifiers and quantities; the server retrieves current prices from its own catalog, checks eligibility and availability, and calculates the final payable amount itself. Testing must be isolated to authorized labs using Burp Repeater, and
- Coupon abuse and stacking exploitationThe article treats coupons as state machines with multiple independent restrictions: per-account usage limits, per-customer global limits, per-order limits, product category restrictions, date ranges, and minimum spend thresholds. Testing involves replaying the apply-coupon request multiple times on the same cart to detect cumulative discounts, applying a single-use code from one account to another to test scope, testing case and whitespace variations to reveal inconsistent normalization, and submitting multiple codes simultaneously to detect stacking failures. The final total must be verified
- Workflow bypass and state verificationWorkflow bypass occurs when the server allows a user to reach a later state without satisfying earlier conditions, such as activating a subscription without payment confirmation. The testing methodology is to complete the normal flow once in a lab and label each request in Burp history, then reset and test whether the final state-changing endpoint independently verifies that required earlier states exist. A secure endpoint must verify server-side payment records or signed provider confirmations, not trust client-supplied values like payment_status=success or the fact that a user visited a succ
- Negative quantities and integer boundary testingThe article requires testing boundary conditions for quantity fields even when prices are server-side: minimum allowed quantity, zero, negative values, maximum permitted quantity, values exceeding the maximum, and fractional values if the field accepts decimals. A negative quantity on a cheap item can be used to offset an expensive item to bring the total to zero or negative; integer overflow (e.g., qty=9999999999 × price=0.01) may overflow to zero or negative; fractional quantities like 0.001 can reduce a $299.99 item to $0.30. The important requirement is that the server rejects invalid quan
- Impact quantification and severity assessmentThe article emphasizes that business logic findings are valuable because they often have directly quantifiable financial impact: 'an attacker can purchase any $299 item for $0.01' is immediately understandable to non-technical stakeholders and floors at High severity on most programs when financial impact is real and repeatable. However, the article cautions against multiplying a single lab result across an entire catalog as confirmed loss; potential scale should be labeled as an estimate and distinguished from observed impact. Severity depends on what an attacker can actually achieve, which a
- Report structure and evidence preservationA strong business logic report opens with the intended behavior, describes the observed behavior, and quantifies impact with evidence from authorized labs. The reproduction sequence must be short and deterministic, including account role, test object, starting state, exact request fields changed, the response, and final state; it must be reproducible by the reviewer in under two minutes. Reports must redact session cookies, payment details, personal data, and other secrets, attach before-and-after comparisons, and explain how any test orders were safely canceled or reset. The report must separ
Bottom line: Business logic vulnerabilities require manual reasoning to understand the application's intended rules before testing them; automated scanners cannot find these flaws because they lack knowledge of business intent. The core testing methodology is to map normal workflows, identify which values should be server-derived versus client-controlled, test one assumption at a time in authorized labs using Burp Repeater, and write reports that clearly prove which rule failed and what financial damage it e
FREE
Part of the Bug Bounty 60-Day Course
0.01 is a valid decimal, and a quantity of -1 is a valid integer. The weakness appears when the server accepts a value or a sequence of actions that violates the application’s own rules.Automated scanners are useful for many vulnerability classes, but they usually don’t understand the commercial intent behind a workflow. They can flag suspicious input patterns; they cannot reliably decide whether a user should be allowed to apply a coupon twice or activate a paid feature before payment. I need to understand the expected behaviour, map the requests that enforce it, and then check whether the server—not just the browser—actually enforces it. That is why careful manual reasoning matters so much here.
🎯 What you’ll master in Day 35
⏱ ~30 min read · 3 hands-on exercises · Burp Suite + PortSwigger Academy
📋 Business Logic Vulnerabilities Bug Bounty – Day 35 of 60 Table of Contents
What business logic vulnerabilities are and why they’re hard to find
When I explain a business logic vulnerability, I describe it as a gap between what an application is supposed to allow and what its server actually permits. SQL injection and cross-site scripting often involve input being interpreted in an unintended way. A business logic flaw can be much quieter: every field may have the right data type, the request may pass validation, and the response may look normal. The problem is that the application has accepted an action that breaks a rule of the product—for example, using a one-time discount twice or activating a subscription without a confirmed payment.
Here is the distinction I want you to remember. Input validation asks, ‘Is this value well-formed?’ Business-rule validation asks, ‘Is this user allowed to perform this action, with this value, at this point in the workflow?’ A price such as 0.01 is syntactically valid. It is still wrong if the catalogue price is $299.99 and the server has no legitimate reason to accept the lower amount. The server must derive sensitive values from trusted records and verify the user’s state before changing anything important.
This is also why I don’t promise that every business logic finding is automatically High or Critical. Severity depends on what an attacker can actually achieve, which accounts are affected, whether exploitation is repeatable, and the real financial or functional impact. A reproducible unauthorised discount may be Medium; a reliable way to obtain paid functionality without payment can be much more serious. In a report, I show evidence and let the programme’s impact model determine the final rating.
Automated scanners can’t find these because they have no model of what the application is “supposed” to do. A scanner testing for SQL injection knows that ' OR '1'='1 is unexpected input. It has no way to know that price=0.01 is unexpected input in a checkout request, because that’s a valid number — the rule that it should equal the catalog price exists only in the developer’s intent.
What makes business logic findings high-value for bug bounty is that they’re often directly quantifiable financial impact. “An attacker can purchase any item for $0.01” is a business impact that programme managers and developers understand immediately. The severity floors at High on most programmes when the financial impact is real.
🧠 EXERCISE 1 — THINK LIKE A HACKER (10 MIN · NO TOOLS)
Before I open Burp, I want you to reason about the rules. Read each scenario and write down the expected server-side check, the request you would inspect in the authorised lab, and the evidence that would prove the rule was not enforced.
- An e-commerce checkout sends this request when you click “Place Order”:
POST /checkout
{"cart_id": "abc123", "items": [{"product_id": "P001", "quantity": 1,
"price": 29.99}], "total": 29.99}
What two modifications would you try first, and why? What would you expect to happen if each one works? - A SaaS platform shows a “Upgrade to Pro” button. When you click it, the flow is: (1) choose plan, (2) enter payment card, (3) payment processed, (4) pro features activated. How would you test whether step 4 can be reached without completing step 3? What would the HTTP request look like for step 4, and how would you replay it?
- A food delivery app allows a “first order free” promo code. The code applies a 100% discount to your first order. After using it on one order, you try it again and get an error “code already used.” What are three different ways this restriction could be bypassed?
Mapping application flows
I start business logic testing by drawing the application’s journeys before changing a single parameter. Turn on Burp Proxy, use the application normally, and record each meaningful action: creating a cart, applying a discount, checking out, upgrading a plan, claiming a reward, or activating a trial. For each journey, note the request that changes state and the response that confirms the change. This gives me a baseline of what a normal user can do.
Next, I mark the values that influence business decisions. These might include product_id, quantity, coupon_code, plan_id, account_id, payment_status, or a referral identifier. A parameter is not vulnerable simply because it appears in a request. It becomes interesting when the server appears to trust a client-controlled value that should instead be checked against a server-side record. I compare the request with the UI, the response, and—where the lab exposes it—the resulting account or order state.
I keep a small flow notebook: action, endpoint, important parameters, expected state change, and evidence. That simple habit stops me from replaying requests blindly. It also helps me spot dependencies: perhaps the confirmation endpoint only works after a payment intent is marked successful, or perhaps a coupon’s usage count changes only after an order is finalised. When I understand those dependencies, I can design a focused test instead of guessing.
Price manipulation and parameter tampering
Price manipulation is the clearest example of trusting the wrong source of truth. Imagine the browser sends a product ID, quantity, unit price, and total. If the server calculates the charge using the submitted price, a user may be able to alter the amount. The secure design is different: the client sends the product identifier and requested quantity; the server retrieves the current price from its own catalogue, checks availability and eligibility, calculates tax and discounts, and creates the payable amount itself. A payment provider should receive that server-calculated amount—not a number the browser gets to choose.
In a permitted training lab, I capture the checkout request in Burp and compare the original request with the lab’s expected result. I change one field at a time so I can identify which control is missing. If I alter a price and the lab confirms an order at the altered amount, I have evidence that the server trusted client-side pricing. I do not use this technique against a live merchant or complete a real underpriced purchase. On an authorised programme, I follow its rules and use a sandbox or an explicitly approved test account; if a test order is created, I stop and coordinate cancellation or reversal as required.
I also inspect the response and resulting state rather than treating an HTTP 200 as proof. A response might accept the request but later recalculate the total, reject payment, or mark the order as pending. The finding is confirmed only when the protected business outcome actually changes in the unauthorised way. I preserve the original and modified requests, redact secrets, and record the expected catalogue price alongside the observed lab result.
Coupon and discount abuse
I treat a coupon as a small state machine, not just a text field. A promotion may be limited to one use per account, one use per customer, one use per order, a particular product category, a date range, or a minimum spend. Those restrictions are separate rules, and I test them separately in a lab. First I learn the intended rule from the interface or programme description; then I observe when the server records the coupon as consumed.
For example, replaying an apply-coupon request may reveal whether the same discount is added repeatedly to one cart. Testing a second authorised test account can reveal whether a supposedly global single-use code is actually scoped only to the first account. Case and whitespace variations can reveal inconsistent normalisation, while submitting two codes can test whether stacking rules are enforced on the server. I change one condition at a time and check the final order calculation, not merely the message displayed beside the coupon field.
There is an important distinction between a logic flaw and a race condition. If two simultaneous requests both redeem a one-time coupon because the usage check and update are not atomic, that is a concurrency problem as well as a business-rule failure. We cover race conditions on Day 36. For today’s tests, keep requests sequential unless the lab specifically asks you to investigate concurrency; that makes the result easier to understand and reproduce.
Workflow bypass
A workflow bypass happens when the server lets a user reach a later state without satisfying the conditions that should come first. The browser may display four screens—choose a plan, enter payment details, process payment, activate the plan—but the browser’s order is not a security boundary. Every state-changing endpoint must independently verify that the required earlier state exists and belongs to the same user, cart, and transaction.
My method is to complete the normal flow once in a lab and label the requests in Burp Proxy history. I identify which request performs the final state change and what proof of payment or authorisation it carries. Then I reset the lab or start a fresh test transaction and check whether the final endpoint rejects an incomplete flow. A secure endpoint should verify a server-side payment record or signed provider confirmation; it should not trust a client-supplied payment_status=success value or the fact that someone visited a success URL.
I pay close attention to transaction binding. A valid payment for cart A must not authorise cart B, and a confirmation token from one account must not activate another account’s subscription. I also check whether the final action is idempotent: replaying a legitimate completion request should not create duplicate orders, credits, or entitlements. In a real programme, I use only the approved test environment and never attempt to obtain goods, services, or premium access without payment.
Negative quantities and boundary conditions
Quantity handling deserves its own pass even when the application calculates prices on the server. The server should enforce a sensible integer range, reject zero or negative quantities where they make no business sense, check stock, and calculate the total using safe numeric types. If it simply multiplies a trusted price by an unchecked quantity, unexpected values can produce incorrect totals or inconsistent inventory changes.
I test boundaries methodically in the lab: the minimum allowed quantity, zero, a negative value, the maximum permitted quantity, a value just above that maximum, and—where the application accepts decimals—a fractional value. I also look for integer overflow or precision errors in the calculation path. The expected result is not always a particular error message; the important requirement is that the server rejects invalid quantities and leaves the cart, inventory, payment state, and account balance unchanged.
Be careful with the phrase ‘negative quantity bug’. A negative number in a request is only a test input, not proof of a vulnerability. Modern systems may reject it at schema validation, clamp it, or recalculate from trusted cart data. I confirm the issue only when the application produces an unauthorised financial or inventory state change. Never use a live order to see whether a negative total results in a credit.
⚡ EXERCISE 2 — BURP LAB (25 MIN)
I use these PortSwigger Web Security Academy exercises because they provide an isolated environment where you can safely observe the failure and learn how to prove it. Follow the lab instructions and keep the testing inside the lab instance.
- Open the PortSwigger Lab: Excessive trust in client-side controls. Use Burp to intercept the checkout request. Modify the price of a jacket to $1 and confirm the order goes through at the manipulated price. Work only in the PortSwigger lab instance; record the original and modified request and the lab response.
- Try the Flawed enforcement of business rules lab. The lab has two discount codes that can’t both be applied at the same time. Find the bypass that allows both to be applied repeatedly. Explain which discount rule is incomplete and capture the final lab total as evidence.
- Try the Low-level logic flaw lab. Use an integer overflow in the quantity field to bring the total below $0 and purchase a jacket for free. Keep this inside the lab and note how the application handles the boundary value.
Writing the report that pays
A strong business logic report tells a reviewer exactly which rule failed and how I proved it. I open with the intended behaviour, then describe the observed behaviour, and finally quantify the impact using evidence from the authorised lab or test environment. Avoid vague claims such as ‘checkout can be hacked’. State which endpoint accepted which unauthorised value, what the server returned, and what persisted afterwards.
I keep the reproduction sequence short and deterministic. Include the account role, test object, starting state, exact request fields changed, response, and final state. Attach a before-and-after comparison and redact session cookies, payment details, personal data, and other secrets. If the test created an order or entitlement, explain how it was safely cancelled or reset. A reviewer should be able to reproduce the behaviour without guessing what you clicked.
For impact, calculate the loss per affected transaction only when the evidence supports it. Do not multiply a single lab result across an entire catalogue and call that a confirmed loss. You can describe potential scale as a clearly labelled estimate, but distinguish it from observed impact. Severity should reflect realistic exploitability, prerequisites, affected users, and business consequences—not an inflated headline. Finish with a remediation that addresses the root cause: server-side price lookup, atomic coupon redemption, explicit workflow-state checks, transaction binding, and safe numeric validation.
Severity: Assess according to the authorised programme’s policy and demonstrated impact; do not copy a severity score from a template.
Affected Endpoint: Use the exact endpoint from your PortSwigger lab or authorised test environment.
Summary: In the isolated lab, the checkout flow accepted a price supplied by the client instead of deriving the amount from trusted server-side product data. This allowed the lab transaction to complete with a modified total.
Steps to Reproduce:
1. Start from the lab’s documented initial state.
2. Add the lab product to the cart and intercept the checkout request in Burp.
3. Record the original product identifier, quantity, and price fields.
4. Modify only the price field as instructed by the lab and forward the request.
5. Record the response and verify the resulting state in the lab interface.
[Attach: redacted original request, modified request, response, and lab-state evidence]
Impact: Describe only the impact demonstrated in the lab. For a real authorised programme, quantify potential exposure only when the scope and evidence support the estimate. Do not place or complete a real underpriced order.
Remediation: Treat the server-side product catalogue as the source of truth. Accept product identifiers and permitted quantities from the client, retrieve prices on the server, calculate discounts and totals server-side, and bind the payment confirmation to the exact cart and transaction.
⚡ EXERCISE 3 — WRITE THE REPORT (15 MIN)
Convert your PortSwigger lab finding into a full report:
- Write the price manipulation report using the PortSwigger lab as your finding. Use the actual endpoint, the actual request you modified, and the actual response. The PoC must be reproducible by the reviewer in under two minutes.
- Write the coupon bypass report separately for the alternating-code lab. Explain why the technical control (“can’t use two codes at once”) failed to enforce the business intent (“each code is single-use per session”). This is the kind of nuanced explanation that separates a hunter who understands the class from one who just found it by clicking.
- Rate both vulnerabilities. For the price manipulation: should it be High or Critical? For the coupon bypass: what financial damage per exploitation justifies the severity you assign? Defend your ratings.
💰 Quick check: a checkout endpoint validates that quantity is a positive integer and price matches the catalog exactly. The only user-controlled fields are product_id and quantity. What business logic test should you still try?
📋 Day 35 reference card
✅ Mark Day 35 complete
By the end of this lesson, you should be able to map an e-commerce or SaaS workflow, identify the business rules behind price, quantity, coupons and payment state, test those rules safely in a lab, and write a report that separates observed evidence from estimated impact.
❓ Frequently asked questions
Why can’t automated scanners find business logic vulnerabilities?
What is the most common business logic finding in e-commerce?
What severity do business logic vulnerabilities get?
How do I test for workflow bypass?
Is it okay to test price manipulation on a real order?
Can I find business logic bugs on SaaS platforms, not just e-commerce?
📚 Further reading
- Race Conditions Bug Bounty — Day 36 — coupon abuse and business logic findings are often race conditions in disguise — a single-use code that can be used twice in concurrent requests is both.
- Burp Suite Deep Dive — Day 5 — Burp Repeater is the main tool for replaying and modifying business logic requests — the manipulation workflow starts here.
- External: PortSwigger — Business Logic Vulnerabilities — the most complete free lab series for business logic, covering price manipulation, coupon abuse, workflow bypass, and low-level flaws.
- External: OWASP — Business Logic Attacks — the OWASP reference on business logic testing methodology and the class taxonomy.

