Skip to main content

Free 30-min security demo  — We'll scan your real code and show live findings, no commitment Book Now

Offensive360
Academy Business Logic Flaws
Advanced · 25 min

Business Logic Flaws

Discover how price manipulation, negative quantities, and workflow bypass defeat security when logic lives client-side.

1 Logic Bypass Attack Patterns

Business logic flaws exploit gaps in the intended application workflow rather than technical vulnerabilities. Automated scanners often miss them because they require understanding the business context.

Price manipulation:

POST /api/checkout
{ "items": [{ "id": "laptop123", "price": 0.01, "quantity": 1 }] }
# Vulnerable server trusts client-submitted price!

Negative quantity:

POST /api/cart/add
{ "item": "gift-card-100", "quantity": -10 }
# Result: $-1000 applied to cart, effectively getting paid to shop

Workflow bypass:

# Normal flow: Step 1 (add items) → Step 2 (enter payment) → Step 3 (confirm)
# Attacker goes directly to:
POST /api/orders/confirm?orderId=PENDING_ORDER_ID
# Without completing payment step — order is confirmed for free

Race conditions: Submitting two requests simultaneously to redeem the same coupon code or transfer more funds than the balance allows.

2 Server-Side Business Rule Validation

Every business rule must be enforced server-side on every request. Client-side constraints (disabled buttons, hidden fields, validation in forms) are trivially bypassed.

Price verification:

async function processCheckout(cartItems) {
  // NEVER trust client-submitted prices
  let total = 0;
  for (const item of cartItems) {
    // Always look up the real price from the database
    const product = await Product.findById(item.productId);
    if (!product || product.stock < item.quantity) {
      throw new Error("Invalid item or insufficient stock");
    }
    // Use server-side price, ignore client-supplied price
    total += product.price * item.quantity;
  }
  return total;
}

Quantity validation:

if (quantity <= 0 || !Number.isInteger(quantity) || quantity > 100) {
  throw new Error("Invalid quantity");
}

Workflow state validation:

// Verify the previous step was completed before allowing next step
if (order.status !== "payment_pending") {
  throw new Error("Invalid order state for confirmation");
}

Knowledge Check

0/3 correct
Q1

Why are business logic flaws often missed by automated security scanners?

Q2

What is the correct defense against price manipulation in an e-commerce checkout?

Q3

How can a race condition enable free coupon redemption?

Code Exercise

Verify Server-Side Price

The checkout function trusts the client-submitted price. Fix it to look up the actual price from the database.

javascript