API testingAug 30, 202415 min read

Mastering API pentesting: Part 2 - business logic, rate limits, GraphQL

API4:2023 (resource consumption) and API6:2023 (sensitive business flows) are where the most expensive bugs hide. Plus GraphQL aliasing, depth attacks, and introspection - the failure modes scanners cannot find.

VI
Vikram Iyer
API specialist · Staatse

Where Part 1 left off

Part 1 covered inventory, authentication, and authorization - the OWASP API Top 10 categories API1, API2, API5, and API9. Part 2 picks up the more interesting territory: API4 (resource consumption), API6 (business flows), and GraphQL-specific attack surface.

37%Findings are business-logic
API6:2023Sensitive business flows (new in 2023)
1000xCost amplification via GraphQL aliasing
72%Rate-limiters bypassable somewhere

Business logic flaws (OWASP API6:2023)

These are the findings clients pay us for. They don't show up in scanners because they require understanding what the API is supposed to do. The OWASP API Top 10 added "Unrestricted Access to Sensitive Business Flows" as a new category in the 2023 edition specifically to elevate this class.

Scanners cannot find these. Business-logic flaws require an understanding of intent. A negative quantity is a valid integer; a parallel request is a valid HTTP call. Only a human with context spots them. This is why OWASP added API6 as a standalone category.

The three patterns we look for

1
Race conditions

Double-spend on a credit transfer, double-discount on a checkout, duplicate redemption of a one-time code. Issue 20-50 parallel requests, watch for inconsistent state. Tools like Burp's "Turbo Intruder" or PortSwigger's single-packet attack technique. Documented in PortSwigger's Web Security Academy.

2
State machine skipping

Many APIs implement workflows (order → paid → shipped). The vulnerable ones don't enforce transitions on the server. You skip "paid" and POST directly to "shipped". OWASP API6:2023 calls these out by name.

3
Quantity / pricing manipulation

Submit negative quantities. Submit prices that should be server-determined. Submit fractional values on integer fields. Surprisingly often, the server trusts the client.

# State-skip example - the order workflow
POST /api/orders/12345/ship HTTP/1.1
Authorization: Bearer <our-token>

# Expected: 409 Conflict - order not yet paid
# Observed:
HTTP/1.1 200 OK
{"status": "shipped", "tracking": "..."}

Rate-limiting bypass (OWASP API4:2023)

API gateways rate-limit by API key, by IP, by user. The bypass surface is wider than most teams think.

Bypass vector OWASP API4 sub-category What it costs to fix
IP rotation via residential proxy Always available MED - device fingerprinting
API-key signup at scale When signups are free LOW - per-account limits + KYC
Endpoint version gap /login limited, /login/v2 not LOW - unify config
Header bypass X-Forwarded-For trusted LOW - strip at edge
Async / batch endpoints Counted as one call MED - count inner ops
Header spoof bypass
64%
Version-gap bypass
48%
Batch / async bypass
31%
IP rotation effective
84%

GraphQL-specific surface

GraphQL adds attack surface that REST APIs don't have. The OWASP GraphQL Cheat Sheet is the reference for hardening; the four patterns below are what we test for on every engagement.

1
Introspection in production

Is __schema enabled in production? It usually shouldn't be. Most teams forget to disable it post-launch because every dev needs it locally. The GraphQL spec itself recommends disabling in production.

2
Query depth attacks

Deeply nested queries that explode server cost. user { friends { friends { friends { friends { name } } } } } can fan out to thousands of resolver calls. Apollo Router supports max-depth caps; most homegrown gateways don't.

3
Aliasing for batch abuse

Request the same field 1000 times in one query via aliases. One HTTP call, thousands of resolver invocations. Bypasses naive rate-limiting completely - this is the GraphQL equivalent of the rate-limiting batch bypass.

4
Field-level authorization gaps

Resolver-level auth is often inconsistent. The top-level query is gated; the nested field isn't. order.customer.email leaks even when customer directly is denied. Apollo's documentation calls this out by name.

# Aliasing abuse - 100 lookups in one HTTP call
query {
  a1: user(id: 1)  { email }
  a2: user(id: 2)  { email }
  a3: user(id: 3)  { email }
  # ...
  a100: user(id: 100) { email }
}
# One request to the rate-limiter; 100 DB lookups behind it.

The GraphQL findings that hurt are never schema-level. They're resolver-level: the field that wasn't gated, the alias that wasn't counted, the depth that wasn't capped. The schema looks safe; the runtime isn't.

- Staatse API retrospective, 2024

Engagement breakdown

Where the time goes on a typical 2-week API engagement.

Recon + inventory (API9)
20%
Auth + authz (API1/2/5)
25%
Business logic (API6)
30%
Rate limit + abuse (API4)
10%
Reporting + retest
15%
{ chart placeholder · finding distribution Part 1 vs Part 2 }
Fig 1 · Where Part-2 findings (business logic, abuse, GraphQL) sit relative to authz findings from Part 1.

Key takeaways

  • Business logic (OWASP API6:2023) is where the most expensive bugs live - scanners cannot find them.
  • Rate limiting (API4:2023) must be tested with actual abuse vectors (IP rotation, header spoof, version gap) - configured doesn't mean enforced.
  • GraphQL introspection should be off in production. Depth + alias caps must be enforced at the gateway (Apollo Router supports both), not relied upon at the schema.
  • Field-level authorization needs the same rigour as top-level - the nested field is where the data leaks.

Closing

API engagements are some of our most useful per-hour-of-work findings, because the patterns are consistent across customers. If you're shipping a new API and want a structured pre-launch review, our web/API engagement covers this.

References & further reading

  1. OWASPAPI4:2023 - Unrestricted Resource Consumption
  2. OWASPAPI6:2023 - Unrestricted Access to Sensitive Business Flows
  3. GraphQLGraphQL specification - introspection
  4. OWASPGraphQL Cheat Sheet
  5. PortSwiggerWeb Security Academy - GraphQL API vulnerabilities
  6. PortSwiggerRace conditions: web security academy
  7. Apollo GraphQLSecuring your GraphQL API
Need a hand?

Need help securing your business?

If anything in this report applies to your stack, we can scope a focused assessment within two business days.