Home / Blog / Business logic testing checklist
Playbooks
Business logic testing checklist: prices, coupons, workflows and race conditions
A practical business logic testing checklist for web apps and APIs: the rule to confirm, how to try to break it, and the fix that holds.
Cyberlop Labs · Updated · 15 min read
A business logic testing checklist is a list of checks that try to break your application's own rules: prices, coupons, quantities, limits, workflow order and parallel requests. Write each rule as an invariant, test it with real accounts on staging, prove the result, fix it on the server and replay the exact exploit.
- Write down your invariants first: a rule you cannot state is a rule you cannot test.
- The server must decide prices, totals, eligibility and workflow state; the client only suggests.
- Scanners miss logic flaws because the traffic is valid, so test with real accounts and real flows.
- Race conditions need parallel requests, repeated runs and a reconciliation of the final totals.
- Turn every fixed flaw into an automated regression test, and prove the fix by replaying the exact exploit.
A business logic testing checklist is a written list of the rules your product depends on, each paired with a way to break that rule using only features the app already offers. Work through prices, quantities, coupons, workflow order, limits, timing and parallel requests, and confirm the server enforces each rule itself. Scanners rarely find these flaws because nothing looks malformed.
The list suits engineering and product teams, not only testers. Use it before a launch, to brief a pentester, or after a release that touched payments, onboarding or approvals. Each section gives the rule to confirm, test ideas you can run on a staging copy today, and the fix that usually holds. It follows the OWASP Web Security Testing Guide business logic chapter and adds the cases product teams meet in payments and promotions.
What is business logic testing, and why is it different?
A business logic flaw is a case where the application does exactly what the code says, but the code does not say what the business meant. OWASP's test is practical: if spotting the flaw takes knowledge of the business, you are probably looking at a logic problem. The request is valid, the user is signed in, and the response is a clean 200. The damage is a refund paid twice, a free upgrade, or stock that nobody paid for.
Injection flaws break the parser. Logic flaws break a promise, so the standards file them elsewhere: MITRE groups them under CWE-840, Business Logic Errors, a category whose members include unverified ownership, missing limits, single-use actions and workflow enforcement. MITRE marks the category itself as prohibited for mapping real vulnerabilities, so a finding should map to a member such as CWE-841 or CWE-770. OWASP places the wider theme under A06:2025 Insecure Design.
The root cause is often something you already know by another name: weak server-side authorisation, missing input validation, or no rate limiting. Testing for logic flaws is mostly testing whether those controls exist at the exact point where money, data or state changes.
Can scanners find business logic flaws?
An automated scanner sends payloads and watches for signs: an error message, a reflected script, a delayed response. A logic flaw gives none of those signs. Changing a quantity from 1 to -1 returns a normal page. Whether that page is a bug depends on a rule the scanner has never been told.
A tool needs to know the rule, reach the state where it applies (a paid order, a trial account) and recognise a wrong outcome. Most manage the second at best. A person, or a system that reads your code and your flows, supplies the rest.
The OWASP Web Security Testing Guide makes the same point: tools struggle with context, so people have to run these tests. A clean scanner report therefore tells you little about logic risk. Our post exploited, not suspected shows how we separate proven findings from guesses, and why your scanner has one login covers the related blind spot of testing from a single account.
Why do business logic flaws matter in 2026?
Because more attacks now start inside the application itself. The 2026 Verizon Data Breach Investigations Report found that 31% of breaches began with a software vulnerability, ahead of stolen passwords. Not all of those are logic flaws, but a logic flaw needs no malware and no stolen credential: only a valid account.
OWASP's 2025 list points the same way. A06:2025 Insecure Design maps 39 CWEs and 729,882 occurrences, with a maximum incidence rate of 22.18% and an average of 1.86%. A01:2025 Broken Access Control, the neighbour that logic flaws often overlap with, reports that 100% of the applications tested had some form of it. Getting it wrong is expensive: IBM's Cost of a Data Breach Report 2026 gives a global average of 4.99 million US dollars, a 12% rise on the year before.
How do you prepare: flows, rules and invariants?
You cannot test a rule nobody wrote down. Spend an hour before you start and produce three short lists. This is the same discipline as a threat model, kept deliberately small.
- Flows that move money or value. Checkout, subscription change, refund, wallet top-up, payout, credit grant, referral reward, gift card, invoice approval.
- Flows that change state. Order status, KYC status, account activation, document approval, password reset, trial to paid, cancellation.
- Invariants. Statements that must always hold. For example: an order total equals the sum of server-side prices; stock never goes below zero; a coupon is used once per customer; a refund never exceeds the amount paid; only the approver can approve.
Each invariant becomes one or more test cases. Write them as sentences a product manager would agree with. If the team cannot agree on one, you have found your first design problem.
You also need accounts: two ordinary accounts in one tenant, one in another tenant, one with elevated rights and one brand-new account. Many logic flaws only appear when a second account touches the first one's object.
The business logic testing checklist at a glance
The table below is the short version. The sections after it explain each row with test ideas and fixes. Tick a row only when you have tried to break the rule and the server refused.
| Area | Rule to confirm | Quick test | Usual fix |
|---|---|---|---|
| Prices and totals | Server decides every price and total | Edit price, total or currency in the request | Recalculate from the catalogue on the server |
| Quantities | Quantity is a positive whole number within stock | Send 0, -1, 0.5, a huge number | Strict type, range and stock checks |
| Coupons and credits | Each code is valid, eligible and used as allowed | Reuse, share, expire, apply to wrong items | Record redemptions, check eligibility server-side |
| Workflow order | Steps happen in order and only once | Call step 3 without step 2; repeat step 3 | Explicit state machine on the server |
| Limits | Sensitive actions have usage limits | Repeat the action past the stated limit | Per-account limits with a stored counter |
| Race conditions | Parallel requests cannot beat a check | Send the same request many times at once | Atomic updates, unique constraints, locks |
| Timing and expiry | Time-based rules use server time | Use expired tokens, offers and trials | Check expiry at the moment of use |
| Ownership and roles | Only the right account can act on an object | Use account A's object ID from account B | Ownership check on every action |
| Files and payments | Uploads and payment results are verified | Wrong file type; fake payment callback | Verify content and signed provider events |
How the checklist maps to OWASP WSTG v4.2 and CWE
Use this table to show an auditor or a client which public test each row covers. WSTG v4.2 numbers its business logic tests 4.10.1 to 4.10.9.
| Checklist area | WSTG v4.2 test | Closest CWE |
|---|---|---|
| Prices, quantities, coupons | 4.10.1 Business Logic Data Validation; 4.10.2 Ability to Forge Requests | CWE-639, CWE-837 |
| Hidden fields and signed values | 4.10.3 Integrity Checks | CWE-841 |
| Timing and expiry | 4.10.4 Process Timing | CWE-362 |
| Limits and abuse | 4.10.5 Number of Times a Function Can Be Used; 4.10.7 Defenses Against Application Misuse | CWE-770, CWE-837 |
| Workflow order | 4.10.6 Circumvention of Work Flows | CWE-841 |
| Files | 4.10.8 Unexpected File Types; 4.10.9 Malicious Files | Covered in file upload guidance |
Prices, totals and currency
The rule: the browser or app may display a price, but only the server may decide it. Any value the client sends that influences money is a candidate for tampering, which is the idea behind price manipulation and parameter tampering.
Test ideas
- Intercept the checkout request and change the unit price, line total, order total, shipping cost, tax amount or currency. Does the order complete at the edited value?
- Change the product ID after the price has been fetched. Some carts price the item at add time and let the ID change later.
- Add hidden fields to the request, such as a discount amount or a
roleorplanfield, and see whether the server accepts them. This is the pattern behind mass assignment. - Check rounding. Split a total across many small lines and see whether rounding in your favour accumulates, a known pattern called rounding abuse.
What a good fix looks like
Never accept prices, totals or discount values from the client. Accept only identifiers and quantities, then compute everything from your own catalogue at the time of payment. Compare the amount the payment provider reports with the amount you expected, and refuse to fulfil if they differ. Use integer minor units (paise, fils, cents) for money, not floating point numbers.
Quantities and numeric limits
The rule: every number has a valid range, and the server enforces it. The classic failures are the negative quantity that turns a purchase into a credit, and the oversize number that wraps around or exceeds stock.
Test ideas
- Send quantity values of 0, -1, 1.5, 1e9, a very long number, an empty string and the text "null".
- Transfer or withdraw a negative amount. A negative transfer from A to B can quietly become a transfer from B to A.
What a good fix looks like
Validate type and range on the server for each numeric field, not only in the form. Reject, do not clamp, values you did not expect, and log the rejection. Check stock inside the same database transaction that reduces it, so two buyers cannot both succeed on the last unit.
Coupons, credits and referral rewards
The rule: a code can only be redeemed by an eligible account, on eligible items, within its limits, and the redemption is recorded exactly once. Promotions are where product rules are most numerous and least tested. The relevant patterns are coupon abuse, referral fraud, trial abuse, loyalty points abuse and gift card fraud. For a worked example of how discount rules collide, see the teardown in exploited, not suspected; this checklist covers the surrounding cases.
Test ideas
Single-use codes and credits
- Redeem a single-use code twice, once after the other and once in parallel.
- Apply the code, then change the cart to ineligible items before paying. Is eligibility checked again at payment?
- Create several accounts with plus-addressed emails (
name+1@example.com) and see whether each earns a signup or referral reward. - Start a trial again with the same email, phone number, card or device and see what your controls actually key on.
What a good fix looks like
Store each redemption as a row tied to the account and the order, with a unique constraint where the rule says once. Recheck eligibility at the final step, not only when the code is entered. Pay referral rewards only after a real, non-refundable event, and reverse them when the underlying order is reversed. Decide, in writing, what counts as the same customer.
Workflow order and state transitions
The rule: each object moves through a fixed set of states, and the server rejects any move that is not allowed. OWASP calls this circumvention of work flows, and MITRE lists CWE-841, Improper Enforcement of Behavioral Workflow among the members of CWE-840. In code it is a state machine that exists only in the front end.
Test ideas
- Skip steps. Call the "confirm order" endpoint without paying, the "activate account" endpoint without verifying the email, or the "ship" endpoint on an order that is still pending. This is workflow bypass.
- Repeat a step. Submit the final step twice. Does fulfilment happen twice?
- For approvals, confirm that the requester cannot approve their own request and that approval by one role does not satisfy a second-approver rule (separation of duties).
What a good fix looks like
Model the states and allowed transitions in one place on the server. Every endpoint that changes state must name the state it expects and refuse otherwise. Store who did what and when. Make the final step idempotent, so repeating it with the same key returns the first result instead of repeating the work.
Usage limits and abuse of sensitive flows
The rule: any action that costs money or reputation when repeated has a limit that the server counts. OWASP lists this as API6:2023 Unrestricted Access to Sensitive Business Flows and gives scenarios such as automated buying of a limited release to resell it, booking and cancelling most of a flight's seats, and farming a referral programme with generated accounts. Related patterns are limit overrun, SMS pumping, card testing and API abuse.
Test ideas
- Find every action with a stated limit (five invites, three free exports, one trial, ten password resets per day) and try the limit plus one, from a single account and from a fresh one.
- Check that the limit lives on the account or tenant, not only on the IP address or session.
What a good fix looks like
Count against the account, the tenant and, where it makes sense, the payment instrument, and store the counter server-side. Add cost-aware limits for expensive actions, and alert on unusual volumes so a person looks. Technical controls such as bot detection help, but OWASP is explicit that the business has to decide which flows are sensitive first. See also rate limiting.
How do you test race conditions and double-spend?
The rule: when two requests arrive at the same moment, the outcome is the same as if they arrived one after the other. A race condition breaks that. CWE-362 from MITRE covers the case where two pieces of code share a resource and the timing lets one change it while the other is mid-use. On the business side this appears as double spending a balance, using a one-time code twice, or withdrawing more than the account holds. A closely related bug class is time of check to time of use.
Test ideas
Choose the targets
- Pick every "check, then change" action: redeem a code, spend a balance, claim a gift card, accept an invite, use the last item in stock, withdraw funds, vote.
Fire the requests
- Send the same request ten to fifty times in parallel and count how many succeeded. PortSwigger teaches a three-step method (predict, probe, prove) and a single-packet technique that delivers 20-30 requests in one TCP packet, so network jitter cannot hide the race.
- Repeat the test several times. A race may succeed one run in ten, so a single failed attempt proves nothing.
Reconcile the result
- After the test, reconcile: balances, stock counts, redemption rows and ledger totals should agree with the number of successful responses.
Race-condition targets and the safe result
Run each target with parallel requests and compare with the expected result below.
| Target | Parallel test | Safe result |
|---|---|---|
| Single-use coupon | Redeem 20 times at once | One success, nineteen refusals |
| Wallet balance | Withdraw the full balance 10 times at once | Balance never below zero |
| Last unit of stock | Two buyers, one unit | One order, one refusal |
| Refund | Refund the same order twice at once | One refund, ledger agrees |
| Invite or seat limit | Send invites past the plan limit together | Stops at the limit |
What a good fix looks like
Make the check and the change one atomic step. Use a single conditional update (UPDATE ... WHERE balance >= amount), a database unique constraint on the redemption, a row lock inside a transaction, or an idempotency key, which Stripe documents as storing the first request's result and replaying it for any repeat. Do not rely on an in-memory check in one application instance when you run several. Then write a test that fires parallel requests and asserts the final totals.
Timing, expiry and time windows
The rule: time-based rules use the server clock and are checked at the moment of use.
Test ideas
- Use an expired coupon, reset link, invite or download URL and confirm the server refuses it.
- Change the device date or time zone and see whether any time-based decision follows the client.
What a good fix looks like
Store expiry as an absolute timestamp on the server, compare against server time when the action is performed, and test the boundary values. Treat any timestamp the client sends as information, never as a decision.
Ownership, roles and cross-account actions inside flows
Logic flaws and access control flaws overlap more than most checklists admit. A refund flow that works only for the buyer is a logic rule; a refund endpoint that accepts anyone's order ID is an access flaw that lives in the same rule. For each flow on your list, repeat the key steps with a second account and ask what it can reach that it should not.
- Use account B to view, edit, cancel, refund or approve an object created by account A. This is the IDOR or BOLA family; see the IDOR checklist and broken object level authorization for detailed steps.
- Use an ordinary account to call an admin or finance function directly. Hidden buttons are not a control.
The fix is the same one that fixes access control generally: check ownership and permission on the server for every action, using the identity from the session and never an ID from the request. The access control testing checklist covers how to plan accounts and record results.
How do you test files, payments and integrity checks?
Two more OWASP items belong on a product team's list because they touch real money and real data.
Uploads
For uploads, the rule is that the server accepts only the types and sizes it expects and never treats an upload as trusted. Test an unexpected file type, a file whose extension and content disagree, an oversize file and a file with an unexpected name. See file upload vulnerability for the technical side.
Payments and refunds
Payment checks
The rule is that fulfilment follows a verified payment event, not a browser redirect. Test these cases:
- Open the "payment successful" URL directly without paying.
- Replay or forge the provider's callback to your webhook. Is the signature verified, and is the event ID stored so it cannot be applied twice?
- Pay a smaller amount, a different currency or a different order, and see whether fulfilment checks the amount and order reference.
Refund checks
- Check refunds: partial refunds that add up to more than the payment, refunds after chargeback, and refund of a coupon-discounted order. See refund abuse.
For integrity checks, keep any value that matters later on the server, or sign it and verify it when it returns. Token tests belong in the API security testing guide.
What evidence should each test record?
A logic finding is only useful if someone else can reproduce it and a fix can be verified. Keep these six items for each case.
| Item | What to write |
|---|---|
| Rule | The invariant, in one sentence |
| Accounts and state | Which accounts, cart, balance or plan at the start |
| Requests | Exact requests, with the one value you changed |
| Response and effect | Reply, then what the system did (order, balance, email) |
| Business effect | What is lost and how often it can repeat |
| Outcome and date | Whether the control held |
This is the structure a good pentest report uses; read a finding shows how to judge one. Rate severity by business effect and repeatability, and keep confidence separate.
How do you fix a logic flaw and keep it fixed?
Logic fixes are small in code and easy to undo by accident. Three habits keep them in place.
- Turn each invariant into an automated test. "Total equals server-side prices", "code used once even in parallel", "step 3 refuses without step 2". These are cheap security regression tests and they run in your pipeline.
- Add a rules review to design. When a ticket adds a discount, limit or state, ask what must always be true and what the worst repeated use is.
- Re-test the exact exploit after the fix. A new scan does not prove a logic fix; running the same request sequence against the new code does. That is a closed-loop retest.
How often should you run this checklist, and who should?
Run the full list before a major launch and whenever a payment, promotion, onboarding or approval flow changes, and run invariant tests on every build. Have a specialist go through it at least once a year. Compare styles in black box vs grey box vs white box testing, and see the web application penetration testing checklist and the VAPT checklist.
Where Cyberlop fits
Cyberlop checks business-logic flaws and cross-account access as part of black-box, grey-box and white-box pentesting. In white-box mode it reads your code while testing the running app, so a finding can point to the file and line. It reports only what it actually exploited, with the request, the response and the evidence, and a fix is proven by re-running the exact exploit. See how it works and what the evidence looks like.
Questions people ask
Business logic testing checklist: FAQs
What is business logic testing?
Business logic testing checks that your application enforces its own rules when someone uses valid features in unexpected ways: changing a price, repeating a step, skipping a stage or sending requests at the same time. It looks for flaws in design and enforcement rather than in input handling.
What is the difference between a business logic flaw and an injection flaw?
An injection flaw lets an attacker put commands into a parser, and a scanner can spot the effect. A logic flaw uses normal requests that the app accepts because a rule is missing. The traffic looks legitimate, so a person or a rule-aware system has to judge the outcome.
Can automated tools find business logic vulnerabilities?
Only a small part. Tools can flag missing rate limits or obvious parameter changes, but they do not know what your prices, limits and workflows are meant to be. MITRE notes these errors are hard to detect automatically because they involve legitimate functionality. Plan for manual or rule-aware testing.
Which OWASP guide covers business logic testing?
The OWASP Web Security Testing Guide has a business logic chapter covering data validation, forged requests, integrity checks, process timing, usage limits, workflow circumvention, misuse defences, file uploads and payment functionality. The OWASP API Security Top 10 adds unrestricted access to sensitive business flows.
What is an example of a business logic vulnerability?
A checkout that trusts the price sent by the browser, a gift card that can be redeemed twice at the same moment, or a confirmation page that works without payment. The requests look normal; the missing rule is the flaw.
How is a business logic flaw different from IDOR?
IDOR is one cause of broken object-level access: swapping an ID to reach another account's object. A logic flaw is wider and covers order, limits, prices and timing. They overlap when a flow lets one account act on another's order.
See the IDOR entry and the IDOR checklist.
How do you test for race conditions in business logic?
Pick an action that checks then changes something, such as redeeming a code or spending a balance. Send the same request many times in parallel, repeat the run, then reconcile balances and records against the successes. Fix with atomic updates or unique constraints.
Does a business logic fix need a retest?
Yes. A new scan cannot show that a logic rule now holds. Re-run the exact request sequence that broke it, including the parallel version for races, and keep it as a regression test.
Sources
Where the facts come from
- Verizon: 2026 Data Breach Investigations Report
- OWASP: Top 10:2025, A06 Insecure Design
- OWASP: Top 10:2025, A01 Broken Access Control
- IBM: Cost of a Data Breach Report 2026
- OWASP: Web Security Testing Guide v4.2, Business Logic Testing
- OWASP: API Security Top 10 2023, API6 Unrestricted Access to Sensitive Business Flows
- OWASP: Business Logic Security Cheat Sheet
- OWASP Community: Business logic vulnerability
- PortSwigger Web Security Academy: Race conditions
- MITRE: CWE-840 Business Logic Errors
- MITRE: CWE-841 Improper Enforcement of Behavioral Workflow
- MITRE: CWE-362 Race Condition
- Stripe: Idempotent requests
Keep reading
Related articles
Access control testing checklist: sideways, upward and across tenants.
A step-by-step access control testing checklist for web apps and APIs: account planning, sideways, upward and cross-tenant checks, evidence and retests.
API security testing: a 2026 guide to the OWASP API Top 10
A step-by-step API security testing guide: the OWASP API Top 10 (2023) with test cases, BOLA and BFLA checks, JWT, OAuth, GraphQL and a CI/CD plan.
Black box vs white box penetration testing: which to choose
Black, grey and white box penetration testing compared: what each finds and misses, how effort differs, when to choose each and how to combine them.
Which of your rules would break?
Cyberlop checks business-logic flaws and cross-account access, and reports only what it actually exploited, with the request, the response and the line of code. A fix is proven by re-running the exact exploit. Ask us to run it on one of your applications.
Or start with a $199 pilot on one application: thirty days, success criteria agreed before day one, credited against the annual if you convert.