Skip to content

SC-043: API Abuse & Rate Limit Bypass

Scenario Header

Type: API Security / Financial Fraud  |  Difficulty: ★★★★☆  |  Duration: 2–3 hours  |  Participants: 4–8

Threat Actor: Cybercriminal syndicate — API exploitation and financial fraud

Primary ATT&CK Techniques: T1190 · T1059 · T1078.004 · T1499.003 · T1565.001 · T1530 · T1040


Threat Actor Profile

RATE BREAKER is a synthetic cybercriminal syndicate specializing in API vulnerability exploitation targeting financial services platforms. The group combines deep technical knowledge of REST/GraphQL API architecture with expertise in financial system business logic. Their operations focus on identifying and exploiting rate limiting gaps, authentication weaknesses, and business logic flaws in payment processing APIs.

RATE BREAKER operates a structured team: reconnaissance specialists who discover and document API endpoints, exploit developers who craft abuse techniques, and operators who execute the attacks at scale. The group sells API exploit kits and "configs" on underground forums, allowing lower-skilled criminals to replicate their attacks against other targets.

Motivation: Financial — direct monetary theft through payment manipulation, fraudulent transactions, and resale of API exploitation toolkits. Average campaign yield: $500K–$2M before detection.

Public Research Context

This scenario is informed by publicly documented API security incidents:

  • OWASP API Security Top 10 (2023): Broken Object Level Authorization (BOLA), Broken Authentication, and Unrestricted Resource Consumption are the top 3 API vulnerabilities
  • Salt Security State of API Security (2024): 94% of organizations experienced API security incidents — 17% suffered a data breach through an API vulnerability
  • Venmo/Cash App race conditions (public disclosures): Multiple fintech platforms have disclosed race condition vulnerabilities in payment APIs that allowed duplicate transactions
  • Stripe API key exposure incidents: Thousands of API keys discovered in public GitHub repositories — enabling unauthorized payment processing

All technical details in this scenario are synthetic. No real payment processor data or infrastructure is used.


Scenario Narrative

Phase 1 — API Discovery & Reconnaissance (~30 min)

FinEdge Payments is a synthetic payment processing company providing REST APIs for e-commerce merchants. FinEdge processes $2.3 billion in annual transaction volume across 14,000 merchant accounts. Their API platform (api.finedge-payments.example.com) handles payment authorization, capture, refund, and settlement operations.

RATE BREAKER begins reconnaissance on FinEdge's API surface:

Step 1 — Public Documentation Mining:

The attacker discovers FinEdge's public API documentation at docs.finedge-payments.example.com, which includes:

  • OpenAPI/Swagger specification (/openapi.json) with all endpoint definitions
  • Authentication flows (API key + HMAC signature)
  • Request/response schemas with example payloads
  • Rate limit headers documented: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
  • Sandbox environment: sandbox.api.finedge-payments.example.com (no rate limiting)

Step 2 — API Endpoint Enumeration:

Using the OpenAPI spec and brute-force directory scanning, RATE BREAKER maps the full API surface:

Endpoint Method Purpose Auth Required Rate Limit
/v2/payments POST Create payment API key + HMAC 100/min
/v2/payments/{id} GET Get payment details API key 500/min
/v2/payments/{id}/capture POST Capture authorized payment API key + HMAC 100/min
/v2/payments/{id}/refund POST Refund payment API key + HMAC 50/min
/v2/payments/{id}/void POST Void payment API key + HMAC 50/min
/v2/merchants/{id} GET Merchant details API key 200/min
/v2/merchants/{id}/balance GET Merchant balance API key 200/min
/v2/webhooks POST Configure webhooks API key 20/min
/v1/payments POST Legacy endpoint — deprecated API key only (no HMAC) No rate limit
/internal/health GET Health check — exposed None None
/internal/metrics GET Prometheus metrics — exposed None None

Step 3 — Vulnerability Identification:

RATE BREAKER identifies four critical vulnerabilities:

  1. Legacy API without rate limiting: /v1/payments is deprecated but still active, with no rate limiting and weaker authentication (API key only, no HMAC signature)
  2. Exposed internal endpoints: /internal/health and /internal/metrics are accessible without authentication, leaking infrastructure details and transaction volume metrics
  3. BOLA on merchant endpoints: /v2/merchants/{id} and /v2/merchants/{id}/balance accept any merchant ID — no authorization check that the API key belongs to the requested merchant
  4. Rate limit bypass via header manipulation: The X-Forwarded-For header is trusted for rate limiting — injecting different IPs resets the rate limit counter

Evidence Artifacts:

Artifact Detail
WAF Logs Directory brute-force scan: 14,200 requests to non-existent paths — Source: 192.0.2.30 — Tools: gobuster signature — 2026-02-20T14:00:00Z to 2026-02-20T16:30:00Z
API Gateway Requests to /internal/metrics from external IP 192.0.2.30 — 12 requests — Responses: HTTP 200 with Prometheus metrics including transaction counts, error rates, and active merchant count — 2026-02-20T15:22:00Z
API Gateway Requests to /v1/payments — deprecated endpoint — 340 requests from 192.0.2.30 with test card numbers — 2026-02-20T16:00:00Z to 2026-02-20T17:00:00Z
API Gateway BOLA probing: sequential merchant ID enumeration on /v2/merchants/{id} — IDs 1 through 5,000 — Source: 192.0.2.302026-02-20T17:30:00Z
Phase 1 — Discussion Inject

Technical: The attacker discovered a deprecated v1 API that lacks rate limiting and HMAC authentication. What API lifecycle management practices would have prevented this? How should deprecated APIs be decommissioned — sunset headers, traffic monitoring, or hard shutdown?

Decision: The internal metrics endpoint (/internal/metrics) is exposed to the internet. This endpoint reveals transaction volumes, error rates, and active merchant counts. Should internal observability endpoints ever be accessible from external networks? What network architecture prevents this?

Expected Analyst Actions: - [ ] Investigate the directory scanning activity from 192.0.2.30 — this is active reconnaissance - [ ] Audit all API endpoints — identify any that are deprecated, undocumented, or lack proper authentication - [ ] Verify that internal endpoints (/internal/*) are not accessible from external networks - [ ] Review rate limiting configuration — is it IP-based only? Does it trust X-Forwarded-For? - [ ] Check for BOLA vulnerabilities — do API endpoints verify that the authenticated user owns the requested resource?


Phase 2 — Rate Limit Bypass & Authentication Abuse (~35 min)

RATE BREAKER exploits the identified vulnerabilities systematically.

Attack Vector 1 — Rate Limit Bypass via X-Forwarded-For:

The API gateway uses the X-Forwarded-For header value for rate limiting instead of the actual source IP. By rotating the X-Forwarded-For value, the attacker bypasses the 100 requests/minute limit entirely:

POST /v2/payments HTTP/1.1
Host: api.finedge-payments.example.com
Authorization: Bearer sk_live_REDACTED
X-Forwarded-For: 10.0.0.1
Content-Type: application/json

{
  "amount": 100,
  "currency": "USD",
  "source": "tok_REDACTED",
  "description": "Test payment"
}

By cycling through 10,000 spoofed X-Forwarded-For addresses, RATE BREAKER achieves an effective rate of 10,000 requests/minute — 100x the intended limit.

Attack Vector 2 — BOLA on Merchant Balance Endpoint:

Using a single compromised API key (from a small merchant account merchant_12847), the attacker queries the balance endpoint for all 14,000 merchants:

GET /v2/merchants/merchant_00001/balance HTTP/1.1
Host: api.finedge-payments.example.com
Authorization: Bearer sk_live_REDACTED

Response (should return 403 but returns 200):

{
  "merchant_id": "merchant_00001",
  "available_balance": 847293.50,
  "pending_balance": 124500.00,
  "currency": "USD",
  "last_payout": "2026-02-19T00:00:00Z"
}

RATE BREAKER enumerates all 14,000 merchant accounts, collecting balance information and identifying high-value targets for the next phase.

Attack Vector 3 — Legacy API Exploitation:

The deprecated /v1/payments endpoint accepts API key authentication without HMAC signatures. Using the compromised API key, the attacker creates payment authorizations on the legacy endpoint without rate limiting:

POST /v1/payments HTTP/1.1
Host: api.finedge-payments.example.com
X-API-Key: pk_live_REDACTED
Content-Type: application/json

{
  "amount": 0.01,
  "card_number": "4111111111111111",
  "exp_month": 12,
  "exp_year": 2028,
  "cvv": "REDACTED"
}

Evidence Artifacts:

Artifact Detail
API Gateway X-Forwarded-For spoofing detected: 10,000 unique X-Forwarded-For values from single source IP 192.0.2.302026-02-22T08:00:00Z to 2026-02-22T12:00:00Z
API Gateway /v2/merchants/*/balance — 14,000 sequential requests — All from API key sk_live_...12847 — All returned HTTP 200 — BOLA vulnerability confirmed2026-02-22T10:00:00Z
API Gateway /v1/payments — 8,400 requests in 1 hour — No rate limiting applied — API key auth only — 2026-02-22T14:00:00Z
API Gateway Error rate on /v1/payments: 34% (card declines) — 66% success rate — 5,544 authorized payments created — 2026-02-22T14:00:00Z
Application Logs Merchant merchant_12847 API key used to query 14,000 other merchant balances — normal activity for this merchant: 50–80 API calls/day to own endpoints only
Phase 2 — Discussion Inject

Technical: The rate limiter trusts the X-Forwarded-For header for client identification. This is a common misconfiguration in reverse-proxy architectures. How should the rate limiter identify the true client IP when behind a CDN/load balancer? What is the correct way to handle X-Forwarded-For in a multi-proxy architecture?

Decision: The BOLA vulnerability on the merchant balance endpoint exposes the financial data of all 14,000 merchants. This is a critical vulnerability that likely violates PCI DSS requirements. Should FinEdge immediately disable the affected endpoint (impacting legitimate merchants) or deploy a hotfix with authorization checks?

Expected Analyst Actions: - [ ] Block the source IP 192.0.2.30 at the WAF/firewall level - [ ] Revoke the compromised API key sk_live_...12847 - [ ] Audit all API endpoints for BOLA — verify resource ownership checks - [ ] Fix rate limiting to use the true client IP, not X-Forwarded-For - [ ] Disable or properly secure the deprecated /v1/payments endpoint - [ ] Assess data exposure: 14,000 merchant balances accessed without authorization


Phase 3 — Business Logic Exploitation & Financial Fraud (~30 min)

RATE BREAKER escalates to their primary objective: financial fraud through business logic exploitation.

Attack Vector 4 — Race Condition on Payment Capture:

The attacker discovers a time-of-check-to-time-of-use (TOCTOU) race condition in the payment capture flow. When a payment is authorized, it can be captured (settled) exactly once. However, sending multiple simultaneous capture requests before the database transaction commits allows the same authorization to be captured multiple times:

Thread 1: POST /v2/payments/pay_ABC123/capture  → Check: not captured → Process capture → DB commit
Thread 2: POST /v2/payments/pay_ABC123/capture  → Check: not captured (Thread 1 hasn't committed yet) → Process capture → DB commit
Thread 3: POST /v2/payments/pay_ABC123/capture  → Check: not captured (Thread 1 hasn't committed yet) → Process capture → DB commit

Result: A single $500 authorization is captured 3 times, resulting in $1,500 deposited to the merchant account.

RATE BREAKER automates this attack:

  1. Create a payment authorization for $500 using a controlled merchant account
  2. Send 50 simultaneous capture requests within a 10ms window
  3. Average success rate: 3–5 duplicate captures per authorization
  4. Repeat across 200 authorizations over 4 hours
Metric Value
Authorizations created 200
Total capture requests 10,000 (50 per auth)
Successful captures 840 (avg 4.2 per auth)
Expected settlement $100,000 (200 x $500)
Actual settlement (fraudulent) $420,000 (840 x $500)
Excess funds (stolen) $320,000

Attack Vector 5 — Price Manipulation via Unsigned Amount:

On the legacy /v1/payments endpoint, the payment amount is client-specified and not cryptographically signed. The attacker creates a payment flow where:

  1. A legitimate checkout shows $500 to the customer
  2. The API call to /v1/payments submits "amount": 0.01 instead of 500.00
  3. The payment processes for $0.01 but the merchant's system records it as $500.00

This allows the attacker to purchase high-value goods for $0.01 each through compromised merchant integrations.

Evidence Artifacts:

Artifact Detail
Application Logs Race condition: payment pay_ABC123 captured 5 times — Timestamps within 8ms window — Total captured: $2,500 (authorized: $500) — 2026-02-23T09:14:22.001Z to 2026-02-23T09:14:22.009Z
Database 640 duplicate capture records — 200 unique payment IDs with 3–5 captures each — Total excess: $320,000 — 2026-02-23T09:00:00Z to 2026-02-23T13:00:00Z
Settlement System Merchant merchant_12847 settlement queue: $420,000 — Expected (based on authorizations): $100,000 — Discrepancy: $320,000 — Flagged by automated reconciliation at 2026-02-24T06:00:00Z
API Gateway /v1/payments — 340 transactions with amount < 1.00 — Corresponding merchant order records show item values of $200–$800 — Price mismatch pattern — 2026-02-23T14:00:00Z to 2026-02-23T18:00:00Z
Fraud System Traditional fraud rules (velocity, geographic anomaly, card testing) did not trigger — business logic abuse is invisible to transaction-level fraud detection
Phase 3 — Discussion Inject

Technical: The race condition allows multiple captures of a single authorization. What database-level controls prevent TOCTOU race conditions? Consider: row-level locking, optimistic concurrency control (version fields), idempotency keys, and distributed locks.

Decision: The automated reconciliation system detected the $320,000 discrepancy 21 hours after the fraud began. Should real-time reconciliation be implemented? What is the trade-off between real-time monitoring (higher infrastructure cost) and batch reconciliation (delayed detection)?

Expected Analyst Actions: - [ ] Immediately freeze settlement for merchant merchant_12847 - [ ] Identify all duplicate captures — reverse the fraudulent ones - [ ] Implement idempotency keys on the capture endpoint to prevent race conditions - [ ] Audit the /v1/payments endpoint for price manipulation — compare submitted amounts with merchant order values - [ ] Implement server-side amount validation — the payment amount must match the merchant's order system - [ ] Assess total financial exposure and initiate the fraud recovery process


Detection & Hunting

KQL Detection Queries

// Detect X-Forwarded-For spoofing — many unique XFF values from single source IP
ApiManagementGatewayLogs
| where TimeGenerated > ago(1h)
| extend XFF = tostring(parse_json(RequestHeaders)["X-Forwarded-For"])
| extend SourceIP = CallerIpAddress
| summarize UniqueXFF = dcount(XFF), RequestCount = count() by SourceIP
| where UniqueXFF > 100 and RequestCount > 500
| sort by UniqueXFF desc
// Detect BOLA — single API key accessing multiple merchant resources
ApiManagementGatewayLogs
| where TimeGenerated > ago(24h)
| where RequestPath matches regex @"/v2/merchants/[^/]+/balance"
| extend MerchantID = extract(@"/v2/merchants/([^/]+)/", 1, RequestPath)
| extend APIKey = tostring(parse_json(RequestHeaders)["Authorization"])
| summarize UniqueMerchants = dcount(MerchantID), RequestCount = count() by APIKey
| where UniqueMerchants > 10
| sort by UniqueMerchants desc
// Detect race condition — multiple captures on same payment ID within short window
AppRequests
| where TimeGenerated > ago(24h)
| where Url contains "/capture"
| extend PaymentID = extract(@"/payments/([^/]+)/capture", 1, Url)
| summarize CaptureCount = count(),
            MinTime = min(TimeGenerated),
            MaxTime = max(TimeGenerated)
  by PaymentID
| extend WindowMs = datetime_diff('millisecond', MaxTime, MinTime)
| where CaptureCount > 1 and WindowMs < 1000
| sort by CaptureCount desc

SPL Detection Queries

// Detect X-Forwarded-For manipulation
index=api sourcetype=api_gateway
| stats dc(xff_ip) as unique_xff_values, count as request_count by src_ip
| where unique_xff_values > 100 AND request_count > 500
| sort -unique_xff_values
// Detect BOLA — API key accessing unauthorized merchant resources
index=api sourcetype=api_gateway uri_path="/v2/merchants/*/balance"
| rex field=uri_path "/v2/merchants/(?<merchant_id>[^/]+)/balance"
| stats dc(merchant_id) as merchants_accessed, count as request_count by api_key
| where merchants_accessed > 10
| sort -merchants_accessed
// Detect duplicate payment captures (race condition)
index=api sourcetype=api_gateway uri_path="*/capture" method=POST status=200
| rex field=uri_path "/payments/(?<payment_id>[^/]+)/capture"
| stats count as capture_count, range(_time) as time_window by payment_id
| where capture_count > 1 AND time_window < 1
| sort -capture_count

Indicators of Compromise (IOCs)

Synthetic IOCs — For Training Only

All indicators below are synthetic and generated for educational purposes. Do not use in production detection systems.

Type Indicator Context
IP Address 192.0.2.30 Primary attack source — reconnaissance and exploitation
Domain api.finedge-payments.example.com Target API (synthetic)
Domain sandbox.api.finedge-payments.example.com Sandbox environment used for testing
API Endpoint /v1/payments Deprecated endpoint — no rate limit, weak auth
API Endpoint /internal/metrics Exposed internal endpoint
API Key sk_live_...12847 Compromised merchant API key
Merchant ID merchant_12847 Compromised/attacker-controlled merchant account
HTTP Header X-Forwarded-For with rotating values from single source Rate limit bypass technique
Behavior >10 unique merchant IDs queried per API key per hour BOLA exploitation indicator
Behavior >1 capture per payment ID within 1-second window Race condition exploitation
Behavior Payment amounts <$1.00 with order values >$200 Price manipulation indicator

Full Attack Timeline

Time Event ATT&CK ID
2026-02-20 14:00 API reconnaissance — directory brute-force scanning T1190
2026-02-20 15:22 Internal metrics endpoint discovered and queried T1530
2026-02-20 16:00 Legacy /v1/payments endpoint discovered and tested T1190
2026-02-20 17:30 BOLA probing — merchant ID enumeration T1530
2026-02-22 08:00 Rate limit bypass via X-Forwarded-For spoofing T1499.003
2026-02-22 10:00 BOLA exploitation — 14,000 merchant balances exfiltrated T1530
2026-02-22 14:00 Legacy API exploitation — 5,544 unauthorized payments T1190
2026-02-23 09:00 Race condition exploitation — duplicate captures begin T1565.001
2026-02-23 13:00 Race condition exploitation complete — $320,000 excess T1565.001
2026-02-23 14:00 Price manipulation via legacy API — $0.01 payments for $500 goods T1565.001
2026-02-24 06:00 Automated reconciliation flags $320,000 discrepancy
2026-02-24 08:00 Incident response initiated — merchant account frozen

Lessons Learned

Critical Failures

  1. Deprecated API left active: The /v1/payments endpoint was marked deprecated in documentation but remained fully functional with no rate limiting and weaker authentication. API deprecation must include a hard sunset date with traffic monitoring and eventual decommissioning.

  2. Rate limiting based on spoofable header: Using X-Forwarded-For for rate limiting without validating the header chain allows trivial bypass. Rate limiting must use the true client IP determined by the outermost trusted proxy.

  3. No object-level authorization: The merchant balance endpoint performed authentication (valid API key) but not authorization (does this key belong to the requested merchant). BOLA/IDOR vulnerabilities are the #1 API security risk per OWASP.

  4. No race condition protection: The payment capture endpoint lacked idempotency controls, optimistic concurrency, or database-level locking. Financial transaction endpoints require atomic operations with proper concurrency control.

  5. Internal endpoints exposed: /internal/health and /internal/metrics were accessible from the internet, leaking infrastructure details and transaction metrics that aided reconnaissance.

Control Priority OWASP API Risk
Implement object-level authorization on all resource endpoints Critical API1:2023 (BOLA)
Fix rate limiting — use true client IP, not X-Forwarded-For Critical API4:2023 (Unrestricted Resource Consumption)
Decommission deprecated /v1/payments endpoint Critical API9:2023 (Improper Inventory Management)
Implement idempotency keys and database locking on capture/refund endpoints Critical API8:2023 (Security Misconfiguration)
Restrict internal endpoints to private networks only Critical API8:2023 (Security Misconfiguration)
Implement server-side amount validation — cryptographically sign order amounts High API3:2023 (BOPLA)
Deploy real-time transaction reconciliation (not batch) High
Implement API key scoping — keys should only access own merchant resources High API1:2023 (BOLA)
Deploy API security gateway with behavioral analysis Medium API4:2023
Conduct regular API security assessments (OWASP API Top 10) Medium

Cross-References