agentsclimarketplace

21 business logic

Skill 0xGhostCAT/claude-ai-cyber-security-skills/skills/21-business-logic

Hunt business logic flaws — race conditions, workflow state bypass, parameter pollution affecting logic, coupon/discount abuse, refund logic, multi-step process bypass, integer overflow, negative quantities, double-spend. Use when looking for non-CVE bugs that require understanding the app's intended workflow.From its SKILL.md

Install
npx -y skills add 0xGhostCAT/claude-ai-cyber-security-skills --skill 21-business-logic

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.

SKILL.md

10.4 KB, ~2.7k tokens by cl100k_base, as published. Nobody here has run it

Business Logic Flaws

No scanner finds these. They pay the most.

When to invoke

Trigger phrases:

  • "race condition"
  • "logic flaw"
  • "workflow bypass"
  • "double spend"
  • "coupon abuse"
  • "negative quantity"

What is a business logic bug?

A flaw where the technology is correct but the business intent is violated:

  • Coupon meant for one-time use is used 10 times
  • Refund intended for the buyer is sent to the attacker
  • Workflow meant to require admin approval can be skipped
  • Rate limit per user can be bypassed via tenant switching
  • Negative quantity yields negative price → free items + refund

The 11 patterns

Pattern 1: Race conditions (TOCTOU)

Time of check ≠ Time of use:
1. Check: "user has 1 coupon left" → true
2. Use:   "decrement coupon, apply discount"

If you fire 50 parallel requests at step 1+2:
- All 50 checks see "1 left" simultaneously
- All 50 uses apply the discount
- One coupon → 50 uses

Apply to:

  • Coupon / promo code redemption
  • Withdraw money / payout request
  • File upload (each gets unique ID — collision possible)
  • Friend request "accept" (creates relationship + grants permission)
  • Vote (1 user, 1 vote)
  • Like / favorite (intended 1-time per user)
  • Account creation with same email
  • Invitation acceptance
  • 2FA verification (try wrong code in parallel)

Pattern 2: Negative integers

{"quantity": -5, "price": 10}
→ total = -50
→ "refund" or "free + credit"

Test every numeric input:

  • Quantities
  • Amounts
  • Discounts
  • Pages (page=-1)
  • Limits (limit=-1)
  • Offsets

Pattern 3: Float precision

0.1 + 0.2 = 0.30000000000000004 in IEEE-754
"price * quantity * 0.7" tax calc → rounding errors

# Try: price = 0.01, quantity = 100000 → total = 999.99 or 1000?

Pattern 4: Integer overflow

{"amount": 9999999999999999999}  ← overflow signed int → negative
{"page": 2147483647 + 1}         ← INT_MAX + 1 = negative

Pattern 5: Workflow skip (forced state transition)

Normal flow:
  cart → checkout → payment → confirmation → order_created

Bypass:
  cart → POST /api/order/create directly → order_created (skip payment)

OR:
  cart → checkout → cancel → confirmation     (skip payment by canceling mid-flow)
  cart → POST /confirmation with order_id from old order

Pattern 6: Coupon / discount abuse

  • Reuse single-use coupon by:
    • Race condition on apply
    • Logout/login cycle if reset per session
    • Different stripe/payment methods
    • Different cart variations
  • Combine coupons that shouldn't combine
  • Apply at the wrong stage of checkout
  • Apply to wrong items
  • Apply expired coupons (server didn't check exp)
  • Apply admin/internal-only coupons (guessable codes)

Pattern 7: Refund logic

  • Request refund for someone else's order (IDOR)
  • Refund + dispute → double refund
  • Partial refund + cancel → full refund
  • Refund to a different payment method (your card for victim's payment)

Pattern 8: Tier / subscription manipulation

  • Sign up free, then upgrade in a way that bypasses payment
  • Cancel subscription but retain access
  • Pro features available via direct API call ignoring subscription check

Pattern 9: Rate limiting bypass

  • Per-user rate limit bypassed by switching accounts (no per-IP limit)
  • Per-IP bypassed via proxy/IPv6 randomization
  • Per-tenant bypassed by signup of multiple tenants
  • Bypass via aliasing in GraphQL (see [[graphql]])
  • Bypass via batching (one HTTP request, many operations)
  • Bypass via case (some apps lowercase email but rate-limit by exact match)

Pattern 10: Email change / "ownership reassignment"

  • Change email on someone else's account ([[idor-hunting]])
  • "Transfer ownership" feature — does target user have to approve?
  • Forced reassignment via accept-by-default

Pattern 11: Mass assignment

POST /api/user/update
{
  "name": "new name",
  "email": "[email protected]",
  "role": "admin",         ← shouldn't be settable
  "is_verified": true,
  "tenant_id": 1,          ← shouldn't be changeable
  "credits": 1000000,
  "stripe_customer_id": "cus_X"
}

Test every endpoint: throw a fuzzy field list at it.

Step-by-Step Workflow

1. Walk the workflow as a normal user

Sign up, buy something, use a coupon, request a refund. Note every state transition and what triggers it.

2. Map state machine

Draw the flows. Identify:

  • Required steps
  • Optional steps
  • Reversible steps
  • Time-sensitive steps
  • Single-use actions

3. Probe each step independently

For each transition A → B:

  • Can you trigger B directly without A?
  • Can you trigger A twice?
  • Can you fork B from A in parallel (race)?
  • Does the server check A's state when accepting B?

4. Race condition testing

Use Burp Repeater + Send group in parallel (Burp 2023+) or Turbo Intruder.

# turbo_intruder example
def queueRequests(target, wordlists):
    engine = RequestEngine(
        endpoint=target.endpoint,
        concurrentConnections=30,
        requestsPerConnection=1,
        engine=Engine.THREADED
    )
    # Submit 30 identical coupon-apply requests in parallel
    for i in range(30):
        engine.queue(target.req)

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

Burp's "Send group in parallel" (last-byte sync) does this natively now.

5. Negative / overflow fuzzing

For every numeric parameter:

0, -1, -2147483648, 2147483647, 9999999999999999999, 0.0001, 1e10, NaN, Infinity, "1", "1.0", true, false, null, [], {}, "  "

6. Mass assignment fuzzing

Capture an update endpoint. Add common admin-only fields:

{
  ...,
  "role": "admin",
  "isAdmin": true,
  "is_admin": true,
  "admin": true,
  "permissions": ["*", "admin"],
  "verified": true,
  "email_verified": true,
  "phone_verified": true,
  "tenant_id": "other-tenant",
  "stripe_customer_id": "cus_OTHER",
  "credit_balance": 999999,
  "subscription_tier": "enterprise",
  "is_internal": true,
  "is_staff": true,
  "groups": ["admins"]
}

If server silently accepts → mass assignment.

7. Coupon discovery & abuse

# Guess coupon codes
COUPONS=(
    SAVE10 SAVE20 SAVE50 SAVE100
    BLACKFRIDAY CYBERMONDAY HOLIDAY2026
    WELCOME WELCOME10 NEWUSER FIRSTBUY
    FREESHIP FREE
    ADMIN STAFF EMPLOYEE INTERNAL
    TEST DEBUG
    REFER100 REFERRAL
    {company-name}-launch
)

for code in "${COUPONS[@]}"; do
    curl -s -X POST "https://target.com/api/cart/apply-coupon" \
        -H "Content-Type: application/json" \
        -d "{\"code\":\"$code\"}"
done | grep -i 'applied\|success\|discount'

Race condition tools

# turbo intruder (Burp extension) — for HTTP-based races
# nuclei race templates — for known patterns

# Hyper-parallel via http2 in Burp (last-byte sync)
# Send 100 requests with all bytes pre-sent except last bytes
# All servers respond near-simultaneously → race window

# h2c smuggling for races on HTTP/2 backends

Output template

## High: Race condition on coupon application — single-use coupon redeemed 30+ times

### Summary
The `/api/cart/apply-coupon` endpoint validates coupon-usage count before incrementing, allowing a Time-of-Check/Time-of-Use (TOCTOU) race. Sending 30 parallel requests with the same single-use coupon results in 30 successful applications, granting 30× the discount.

### Steps to reproduce
1. Log in as any user
2. Add an item to cart
3. Apply a coupon via UI to obtain a single-use code (e.g., "WELCOME20")
4. Capture the request:
   ```http
   POST /api/cart/apply-coupon HTTP/1.1
   Host: app.target.com
   Cookie: session=USER_SESSION
   Content-Type: application/json
   Content-Length: 30

   {"coupon": "WELCOME20"}
  1. Send 30 of these requests in parallel using Burp Repeater "Send group in parallel" (last-byte sync)
  2. Observe:
    • 27 out of 30 responses return 200 OK with "applied": true
    • Cart total reduces by 27×20% (compounded)
    • Total comes out to negative — credited to account

Impact

  • Unlimited discount stacking → effective free orders + store credit
  • For high-value items (e.g., $5,000 laptop), single attack yields $5,000+ in credit
  • Affects all coupon types: percent-off, fixed-amount, freebie

Suggested fix

  • Use atomic DB operation (UPDATE coupons SET uses_count = uses_count + 1 WHERE uses_count < limit AND code = ?)
  • OR use a distributed lock (Redis SETNX with TTL) keyed by coupon+user
  • OR use a queue with single-threaded processing for redemptions

## Cross-references

- `[[idor-hunting]]` — IDOR + logic = often critical
- `[[ato-chains]]` — many ATOs are logic flaws
- `[[graphql]]` — GraphQL batching = built-in race
- `[[oauth-oidc]]` — auth flow races

## Common pitfalls

1. **Reporting "I clicked refund twice" without proving timing.** Use turbo intruder / parallel requests.
2. **Negative-quantity reports without final payment proof.** Show the actual money/refund movement.
3. **Workflow bypass without showing the "intended" workflow first.** Triage doesn't know your app.
4. **Mass assignment that doesn't actually privesc.** Verify the role change took effect on subsequent requests.
5. **"Coupon stacking" that's only client-side.** Server-side validation may catch it; verify server accepts.

## Severity guide

| Logic flaw | Typical bounty |
|---|---|
| Coupon abuse (full discount stacking) | High ($1k-5k) |
| Negative price / amount → refund | High ($1k-10k) depending on real-money impact |
| Race condition giving 2x of a single-use action | Medium-High ($500-3k) |
| Mass assignment → role privesc | Critical ($3k-15k) |
| Workflow bypass (skip payment) | Critical ($5k-30k) |
| Tier upgrade without payment | High-Critical ($2k-10k) |

## Pro tips

- **Sign up for the free tier.** Most logic bugs are in the upgrade / payment flow.
- **Use a real card with declines.** Some bugs only appear on failed payments.
- **Diff API responses across user roles.** Admin endpoints called by user with logic flaw.
- **Read disclosed reports for your target's competitors.** Same SaaS pattern → similar bugs.
- **Watch the "feature releases" page.** New features = new logic = new bugs.

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.