Stop 37 of 42 · The Back Office · Business logic flaws

Rules that work but can be gamed

The bank’s forms are checked carefully: the customer is signed in, the numbers are valid, the form is complete. But the order form has a box where the customer writes the price, and the teller believes it. Every rule passes, and the bank still gets robbed.

Severity VariesCategory Business LogicThe Back OfficeSources checked 25 Oct 2026

Watch it happen

Play it as

Mallory changes the price on an order form to one cent. The teller’s checklist passes and a pattern-checking scanner finds nothing wrong, so she gets a Gold account for a cent.

Arrival

Mallory walks in to buy a Gold account. Customers fill in an order form, and the app puts the price in a price box.

Mallory says: One Gold account, please.
1 / 5

In bank terms and app terms

In the bankIn your app
Price box on the order formprice or amount sent in the request body
Teller’s checklistValidation that only checks format, login and required fields
Official price listServer-side lookup of price, plan, role and limits
Pattern-checking guardAutomated scanners that look for known code patterns
Reviewer who knows the bank’s intentAI code review or a person reading each important flow

Are you exposed?

You might be exposed if…
  • Your checkout or API takes price, amount, role, plan or discount from the request and uses it directly.
  • Important steps (payment before access, email verified before upgrade) can be skipped by calling the next URL directly.
  • Amounts, quantities or transfers are not checked for negative, zero or absurdly large values.
What to do about it
  1. Look up prices, plans, roles and limits on the server, and treat everything in the request as a suggestion.
  2. Enforce the order of steps on the server: keep a status (pending, paid, shipped) and allow only valid moves, such as granting access only after payment is confirmed.
  3. Validate amounts (no negative, zero or absurdly large values), block self-transfers and reused coupons, and have an AI or a teammate review money flows.

Track these in your to-do list →

What it looks like in code

Business logic fixes are app-specific, but common patterns:

// FIX: Price manipulation — look up price server-side
const PLAN_PRICES = { starter: 9, pro: 29, enterprise: 99 }
const amount = Object.hasOwn(PLAN_PRICES, plan) ? PLAN_PRICES[plan] : undefined
if (amount === undefined) return error("Invalid plan")

// FIX: Race condition — use atomic database operations
await db.query(
  `UPDATE credits SET balance = balance - $1
   WHERE user_id = $2 AND balance >= $1 RETURNING balance`,
  [amount, userId]
)

// FIX: Missing ownership — always filter by authenticated user
const task = await db.query(
  `SELECT * FROM tasks WHERE id = $1 AND user_id = $2`, [taskId, userId]
)

Ask your AI tool to fix it

Paste this into Cursor, Claude, Lovable, Bolt or whatever you build with.

Prompt
Review every checkout, payment, transfer, coupon, subscription and role-change endpoint for business logic flaws. Never trust price, amount, plan, role or discount from the client; look them up on the server. Reject negative or zero amounts, enforce step order (payment confirmed before access), and block self-referrals and reused coupons. Also check Supabase RLS policies and Firebase rules for wrong-column mistakes like auth.uid() = id. Report each flaw and the fix.

Where this comes from

The facts, figures and fixes on this page were checked against these sources on 25 Oct 2026. They are linked so you can check for yourself.

Spot a mistake or something out of date? Report a correction · How these guides are made and checked