OWASP Web Top 10 — A04

Business Logic Flaws

Business Logic Flaws are vulnerabilities that arise from design or implementation errors in the application's business rules. Unlike technical vulnerabilities, they exploit the intended functionality of the application in ways that were never anticipated by developers, making them particularly difficult to detect with automated security scanners.

What Are Business Logic Flaws?

Business Logic Flaws are security vulnerabilities that occur when an application's business logic is not properly designed or implemented. Unlike traditional vulnerabilities like SQL Injection or XSS that exploit technical weaknesses in code, business logic flaws exploit the legitimate features and workflows of an application in ways that violate business rules or security assumptions. They arise when developers fail to anticipate all possible ways users might interact with the application, or when security controls do not adequately enforce business constraints.

These vulnerabilities are particularly insidious because the application behaves exactly as programmed—there are no crashes, error messages, or obvious signs of exploitation. The attacker simply uses the application's own features in an unintended sequence or combination to achieve unauthorized outcomes. For example, an e-commerce site might allow users to apply multiple discount codes in a single transaction, or a banking application might process a withdrawal before verifying the account balance, leading to overdrafts. The code works perfectly from a technical standpoint, but the business logic is fundamentally flawed.

Business Logic Flaws cannot be detected by automated scanners because they require an understanding of what the application is supposed to do, not just how it's implemented. Security researchers must understand the business context, workflows, and expected user behaviors to identify these vulnerabilities. According to OWASP, insecure design (which includes business logic flaws) was introduced as A04 in the 2021 Top 10, reflecting the growing recognition that secure coding alone is insufficient—security must be built into the design from the start.

How It Works

1
Attacker identifies business workflows

The attacker studies the application to understand its business processes, such as checkout flows, account registration, payment processing, or multi-step approval processes. They map out the expected sequence of operations and identify the business rules that govern these workflows.

2
Attacker discovers assumptions or missing validations

Through testing and experimentation, the attacker identifies assumptions made by developers. For example, the application might assume users will always proceed through steps in order, that quantities will always be positive numbers, or that certain operations will only be performed once. They look for places where business rules are not enforced server-side.

3
Attacker manipulates the workflow

The attacker deviates from the intended workflow in a way that violates business logic. This might involve skipping steps in a multi-step process, performing operations in an unexpected order, submitting negative quantities to increase their account balance, or exploiting race conditions by submitting multiple requests simultaneously.

4
Application processes the invalid business state

Because the application only validates technical inputs (data types, length, format) but not business rules, it processes the manipulated request. The server might apply a discount twice, skip a payment verification step, or allow a user to change their order status from "shipped" back to "pending" to trigger a refund.

5
Attacker gains unauthorized advantage

The exploitation results in outcomes that violate business rules and security policies. This could mean obtaining products for free, bypassing payment entirely, manipulating prices, escalating privileges, or accessing features they should not have. The application logs may show normal activity because from a technical perspective, everything worked as coded.

Vulnerable Code Example

Vulnerable — Java / Spring Boot
@RestController
public class CheckoutController {

    @Autowired
    private CartService cartService;

    @Autowired
    private CouponService couponService;

    @PostMapping("/checkout")
    public ResponseEntity<?> checkout(@RequestBody CheckoutRequest req) {
        Cart cart = cartService.getCart(req.getUserId());

        // VULNERABLE: No validation of quantity values
        // Negative quantities can increase balance instead of deducting
        double total = 0;
        for (CartItem item : cart.getItems()) {
            total += item.getPrice() * item.getQuantity();
        }

        // VULNERABLE: Allows applying multiple coupons
        // No check to prevent coupon stacking
        for (String couponCode : req.getCouponCodes()) {
            Coupon coupon = couponService.findByCode(couponCode);
            if (coupon != null) {
                total -= coupon.getDiscountAmount();
            }
        }

        // VULNERABLE: Price calculation done on client-side
        // Trusts the price sent from the frontend
        if (req.getClientCalculatedTotal() < total) {
            total = req.getClientCalculatedTotal();
        }

        // VULNERABLE: Race condition allows double-applying discounts
        // No idempotency check for simultaneous requests
        processPayment(req.getUserId(), total);

        return ResponseEntity.ok("Order placed: $" + total);
    }
}

// Exploitation examples:
// 1. Attacker sets quantity to -10 for a $50 item
//    → Adds $500 to their account instead of subtracting
// 2. Attacker applies same coupon 5 times in request
//    → Gets 5x discount instead of single use
// 3. Attacker modifies clientCalculatedTotal to $0.01
//    → Pays pennies for expensive items
// 4. Attacker sends 3 checkout requests simultaneously
//    → Race condition applies loyalty discount 3 times

Secure Code Example

Secure — Java / Spring Boot (Proper Business Logic Validation)
@RestController
public class CheckoutController {

    @Autowired
    private CartService cartService;

    @Autowired
    private CouponService couponService;

    @Autowired
    private IdempotencyService idempotencyService;

    @PostMapping("/checkout")
    public ResponseEntity<?> checkout(@RequestBody CheckoutRequest req) {
        // SECURE: Check idempotency key to prevent duplicate processing
        if (idempotencyService.isProcessed(req.getIdempotencyKey())) {
            return ResponseEntity.status(409).body("Request already processed");
        }

        Cart cart = cartService.getCart(req.getUserId());

        // SECURE: Validate all quantities are positive
        for (CartItem item : cart.getItems()) {
            if (item.getQuantity() <= 0) {
                return ResponseEntity.badRequest()
                    .body("Invalid quantity for item: " + item.getName());
            }
            if (item.getQuantity() > 1000) {
                return ResponseEntity.badRequest()
                    .body("Quantity exceeds maximum allowed");
            }
        }

        // SECURE: Calculate total server-side only, never trust client
        double total = 0;
        for (CartItem item : cart.getItems()) {
            // Fetch current price from database, don't trust cart
            double currentPrice = productService.getCurrentPrice(item.getProductId());
            total += currentPrice * item.getQuantity();
        }

        // SECURE: Allow only ONE coupon per order
        if (req.getCouponCodes() != null && req.getCouponCodes().size() > 1) {
            return ResponseEntity.badRequest()
                .body("Only one coupon allowed per order");
        }

        if (req.getCouponCodes() != null && !req.getCouponCodes().isEmpty()) {
            String couponCode = req.getCouponCodes().get(0);
            Coupon coupon = couponService.findByCode(couponCode);

            // SECURE: Validate coupon is valid and not already used
            if (coupon != null && coupon.isValid()
                && !coupon.isUsedBy(req.getUserId())) {
                total -= coupon.getDiscountAmount();
                couponService.markAsUsed(coupon, req.getUserId());
            }
        }

        // SECURE: Ensure total is never negative
        if (total < 0) {
            total = 0;
        }

        // SECURE: Mark idempotency key as processed before payment
        idempotencyService.markProcessed(req.getIdempotencyKey());

        processPayment(req.getUserId(), total);

        return ResponseEntity.ok("Order placed: $" + total);
    }
}

// All business rules are enforced server-side:
// - Quantities validated as positive and within limits
// - Prices fetched from authoritative source (database)
// - Single coupon enforcement with usage tracking
// - Idempotency prevents race condition exploits
// - Total cannot be negative

Types of Business Logic Flaws

Price & Payment Manipulation

Exploiting flaws in pricing logic to obtain products or services for less than intended. This includes negative quantity attacks where submitting negative numbers adds money instead of deducting it, coupon stacking where multiple discounts are applied when only one should be allowed, currency rounding errors that allow accumulating fractions of cents, and price tampering where client-submitted prices override server-side calculations. These flaws often arise from trusting client-side input or failing to validate business constraints.

Workflow Bypass

Circumventing intended process flows by skipping required steps or performing operations out of sequence. Examples include multi-step process bypass where an attacker jumps directly to the final step without completing prerequisites, order status manipulation where users change order states in unauthorized ways (e.g., marking items as "shipped" to themselves or "returned" to trigger refunds), and approval process circumvention where mandatory review steps are skipped. These vulnerabilities occur when each step doesn't validate that previous steps were properly completed.

Abuse of Functionality

Using legitimate features in ways that violate business intent or create unfair advantage. This includes referral program fraud where attackers create fake accounts to earn unlimited referral bonuses, loyalty point exploitation through return-and-rebuy cycles or point multiplication tricks, free trial abuse by repeatedly signing up with different email addresses, and resource exhaustion by placing and canceling orders in loops. Unlike other attacks, these use the application exactly as designed, just in ways that violate unstated business assumptions.

Impact

Business Logic Flaws can have severe financial and operational consequences for organizations. Because they exploit core business functions, the damage can be extensive before detection.

Direct financial loss

Attackers can obtain products, services, or currency for free or at drastically reduced prices. This includes inventory theft through pricing exploits, fraudulent refunds, manipulation of account balances, and exploitation of promotional offers. Unlike data breaches, the financial impact is immediate and measurable.

Unauthorized access and privilege escalation

Flaws in role-based workflows can allow users to bypass authentication steps, escalate their privileges from regular user to administrator, or access features and data they should not have permission to view. This can lead to complete account takeover or unauthorized administrative actions.

Business process disruption

Exploits can corrupt business data, create invalid states in workflows, or exhaust resources through automated abuse. For example, thousands of fraudulent accounts created through referral abuse can pollute analytics, inventory manipulation can cause stock discrepancies, and order status tampering can disrupt fulfillment operations.

Reputational damage and competitive disadvantage

When business logic flaws become public, they undermine customer trust and confidence. Competitors or malicious actors can exploit known flaws at scale before fixes are deployed. Public disclosure of simple exploits (like negative quantity bugs) can be particularly embarrassing and damage the organization's reputation for technical competence.

Prevention Checklist

Validate all business rules server-side

Never trust client-side validation or calculations. Every business constraint must be enforced on the server. This includes validating that quantities are positive and within reasonable limits, prices match database values, coupons are valid and not already used, and workflow steps are completed in the correct sequence. Client-side validation is for user experience only, not security.

Implement state machines for multi-step workflows

Design workflows as explicit state machines with defined transitions. Before allowing any state change, verify that the current state and user permissions allow that transition. For example, an order should not be able to go from "shipped" back to "pending" without administrator approval. Track workflow history to detect suspicious patterns.

Use idempotency keys to prevent race conditions

Require clients to submit unique idempotency keys with critical operations. Store these keys and reject duplicate requests with the same key. This prevents attackers from exploiting race conditions by submitting multiple simultaneous requests. Idempotency is essential for any operation involving financial transactions, inventory changes, or state modifications.

Implement rate limiting and anomaly detection

Monitor for unusual patterns that might indicate business logic abuse: users creating many accounts in short succession, rapid sequences of order placement and cancellation, or accounts accumulating loyalty points at impossible rates. Implement rate limits on sensitive operations and flag accounts exhibiting suspicious behavior for manual review.

Document and review business assumptions

Explicitly document all business rules and assumptions. Review these with both business stakeholders and security teams. Ask "what if" questions: What if a user submits a negative number? What if they skip step 2 and go directly to step 4? What if they submit the same request 100 times simultaneously? This threat modeling process reveals logic flaws before they reach production.

Conduct business logic security testing

Unlike technical vulnerabilities, business logic flaws require manual testing by people who understand the business context. Include abuse case testing in QA processes: deliberately try to break business rules, skip workflow steps, submit invalid combinations of parameters, and manipulate timing. Security testing should go beyond automated scans to include thoughtful manual testing of business processes.

Real-World Examples

2016

Starbucks Stored Value

Security researchers discovered a race condition in Starbucks' mobile app that allowed attackers to duplicate stored value on gift cards. By simultaneously sending multiple transfer requests from one card to another, the system would process them in parallel, effectively duplicating money. The vulnerability allowed unlimited funds to be generated from a small initial balance.

2019

Instagram Unlimited Likes

A business logic flaw in Instagram allowed users to like the same post unlimited times by rapidly toggling likes on and off. The backend failed to properly deduplicate rapid sequential requests, causing the like counter to increment with each toggle rather than maintaining a single like state. This allowed artificial inflation of engagement metrics.

2020

Epic Games Free V-Bucks

A workflow bypass vulnerability in Fortnite's purchase flow allowed players to obtain premium V-Bucks currency for free. By manipulating the purchase confirmation sequence and intercepting specific API calls, users could complete transactions without payment processing. The flaw cost Epic Games significant revenue before detection and remediation.

2021

Coinbase $100 Referral Loop

Attackers exploited Coinbase's referral program by automating account creation. The system failed to properly validate that referred users were legitimate and distinct individuals. By creating thousands of fake accounts and completing minimal verification steps, attackers generated substantial referral bonuses before Coinbase implemented stricter validation and rate limiting.

Ready to Test Your Knowledge?

Put what you have learned into practice. Try identifying and fixing business logic vulnerabilities in our interactive coding challenges, or explore more security guides to deepen your understanding.