Your API costs $0.50 per request to process. An attacker's request costs $0.0001 to send.
That 5,000x cost asymmetry is why APIs have become the preferred target for sophisticated DDoS attacks. While web pages can be cached and served from CDN edge nodes, API requests often hit your origin servers directly - every single time.
And here's the uncomfortable truth: most organizations protect their marketing website better than their revenue-generating APIs.
Why APIs Are Different
Traditional DDoS protection was designed for websites. APIs break those assumptions:
| Characteristic | Website | API |
|---|---|---|
| Cacheable | Yes (HTML, images, CSS) | Rarely (dynamic responses) |
| Compute per request | Low (serve static files) | High (database queries, processing) |
| Request rate from legitimate users | 1-10 per minute | 10-1000 per minute (mobile apps) |
| CDN protection | Excellent | Limited (pass-through to origin) |
| JavaScript challenges | Effective | Breaks API clients |
| CAPTCHA | Usable | Impossible |
The API Attack Surface
Modern API architectures expose multiple attack vectors:
1. Public API Endpoints
Any endpoint documented in your API docs is a known target. Attackers don't need to discover anything - you've published the blueprint.
2. Mobile App APIs
APIs serving mobile apps often have higher rate limits (to handle spotty connections) and less protection (no browser to challenge).
3. Microservices Internal APIs
Service-to-service APIs often have no rate limiting at all. One compromised service can DDoS all the others.
4. GraphQL Endpoints
A single GraphQL query can trigger dozens of database operations. Attackers craft queries that are cheap to send but expensive to resolve.
5. Webhook Receivers
Endpoints that accept callbacks from third parties. Attackers can spoof webhook payloads at scale.
API-Specific Attack Patterns
Pattern 1: Expensive Query Exploitation
Attackers identify endpoints that trigger expensive operations:
- Search endpoints with complex filters
- Report generation APIs
- Bulk export endpoints
- Recursive or nested data retrieval
Pattern 2: Authentication Endpoint Abuse
Login and registration endpoints are particularly vulnerable:
- Password hashing is CPU-intensive by design
- Database lookups for every attempt
- Often have higher rate limits "for UX"
- SMS/email verification costs money
Pattern 3: GraphQL Depth Attacks
query EvilQuery {
user(id: 1) {
friends {
friends {
friends {
friends {
posts {
comments {
author {
friends {
# ... infinite nesting
}
}
}
}
}
}
}
}
}
}
Pattern 4: Regex Denial of Service (ReDoS)
If your API validates input with regex, certain patterns cause exponential backtracking:
// Vulnerable regex pattern
const emailRegex = /^([a-zA-Z0-9]+)+@[a-zA-Z0-9]+\.[A-Za-z]+$/;
// Malicious input
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!"
Pattern 5: Payload Amplification
Small requests that generate large responses:
- List endpoints with no pagination limits
- Wildcard searches returning millions of results
- Verbose error messages with stack traces
Pattern 6: gRPC and the Protocol Blind Spot
gRPC uses HTTP/2 as transport and serializes payloads as Protocol Buffers. Most WAFs see HTTP/2 frames. They cannot parse the Protobuf content inside them, and none have per-method rate limiting by default.
We ran our lab harness against three major WAF vendors using five load patterns against our own demo gRPC server. The vendor behavior varies significantly:
| Vendor | Default behavior | Origin traffic | Per-method rate limit |
|---|---|---|---|
| Cloudflare Free | Browser Integrity Check blocks automation clients (error 1010). Bypassed by Chrome TLS fingerprint (uTLS). | 0 frames reach origin with basic tooling | Not configurable on Free (long_lived_grpc read-only) |
| AWS WAF v2 | No gRPC-specific managed rules. CommonRuleSet + BotControl(COMMON) fire on 0 gRPC samples. | All traffic passes through to origin | Rate-based rules count by IP only. Custom URI path rules required. |
| Azure Front Door Premium | DefaultRuleSet 2.1 blocks all application/grpc POSTs with HTTP 403 by default. |
0 frames reach origin - blocked at edge | Blocks all gRPC including legitimate traffic unless explicitly allowed |
What We Measure in Practice
Across DDactic scans of Israeli enterprises and financial institutions, the API surface consistently shows the same gaps. From a sample of scans covering multiple organizations:
- Over 1,150 API endpoints mapped across a six-company scan cohort
- 153 GraphQL endpoints discovered - nearly all without depth or cost limits
- Over 400 login pages identified, most without observable rate limiting on the API origin (only the frontend form is protected)
- Rate limiting detected on fewer than 2% of API assets
- 102 HTTP/2 services, the majority with no gRPC-aware WAF in front
The pattern is consistent: the main domain is behind a CDN. The API subdomain, the mobile backend, and the internal service mesh are on direct IPs with generic WAF rules that were written for web pages.
WAF Vendor Coverage: What the Lab Shows
We ran Patterns 1-6 through an API WAF inspection lab (May 2026) against three vendor configurations on our own intentionally-vulnerable demo server (AcmeScan v1.3.2, Node.js + ApolloServer, Hetzner CPX22). 20 concurrent workers, 10 seconds per run. The table below shows what each vendor's default free/entry-tier configuration actually does - and what requires a paid upgrade.
data/api_lab/). "Docs" rows are vendor documentation only - paid tiers were not provisioned. Cloudflare Free blocks marked with (*) are Browser Integrity Check error 1010 - a client fingerprint check, not API payload inspection. See note below the table.
| Pattern | Cloudflare Free (measured) | AWS WAF Core (measured) | AFD Standard (measured) | Cloudflare Business/Enterprise (docs) | AWS WAF BotControl TARGETED (docs) | AFD Premium (docs + §11 lab) |
|---|---|---|---|---|---|---|
| GraphQL introspection Schema dump at scale |
0 blocks. 83.8 req/s, 100% 200. Full schema delivered through CF Free. | 0 blocks. 64.2 req/s, 100% 200. Full schema through AWS WAF Core. | 0 blocks. No managed WAF policy on Standard tier. | API Shield (Enterprise): can disable introspection per-endpoint. GraphQL depth/size rules available. | No built-in introspection rule. Apollo Server config or custom WAF body-match rule required. | DRS 2.1: no GraphQL-specific rules. Custom body-match rule possible. |
| GraphQL resolved queries High-rate DB-amplified load |
100% blocked (403)* CF BIC error 1010: client fingerprint. Not payload inspection. Browser-emulating attacker passes through. | 0 blocks. 82.3 req/s, 100% 200. AWS WAF Core has no GraphQL awareness. | 0 blocks. 43.4 req/s, 73% pass-through. No WAF policy. | API Shield: per-endpoint rate limiting, GraphQL depth and cost limits. Blocks depth amplification by query structure. | BotControl TARGETED: per-session ML model detects automation behavior. Does not inspect GraphQL depth. | DRS 2.1: no GraphQL payload rules. Custom rate rule possible. |
REST pagination abuseGET /api?limit=10000 |
100% blocked (403)* CF BIC error 1010 (fingerprint). Not parameter inspection. | 0 blocks. 93.7 req/s, 100% 200. limit=10000 not inspected by Core Rule Set. |
0 blocks. Pass-through. No WAF. | Business: custom rule on query param value. API Shield schema validation enforces param ranges from OpenAPI spec. | Custom rate-based rules needed. Core + BotControl do not inspect pagination params. | Custom match rule possible on Standard or Premium. Not included in DRS managed rules. |
| Auth endpoint flooding Credential stuffing at 90+ req/s |
100% blocked (403)* CF BIC error 1010. First block at 0.35s. Browser-emulating bot passes through. | 0 blocks. 89.5 req/s, 100% 401. Origin absorbs each attempt with no WAF throttle. | 0 blocks. Pass-through. No WAF. | Rate Limiting (Business/Enterprise): per-endpoint rules (10 req/min per IP on /auth/login). Bot Management adds ML scoring. |
BotControl TARGETED: per-session token tracking + ML credential stuffing detection. Effective against browser-emulating bots. | Custom rate rule possible. BotManagerRuleSet categorizes bots but does not apply auth-specific rate limits by default. |
| gRPC stream flood HTTP/2 + Protobuf |
BIC fingerprint block. Bypassed with Chrome TLS fingerprint (uTLS, measured in §11 lab). 0 Protobuf inspection. | 0 blocks across all 5 gRPC patterns. No gRPC-aware managed rules. | Standard: no WAF. Pass-through. | long_lived_grpc read-only on Free/Pro. Business: custom rate rules by URI prefix only. Enterprise: can enable gRPC forwarding. |
No gRPC-specific managed rules. BotControl TARGETED fires on HTTP metadata, not Protobuf payload. | Blocks all gRPC. AFD Premium DRS 2.1 returns HTTP 403 for all application/grpc POST by content-type. Measured in §11 lab. Legitimate gRPC also blocked unless explicitly whitelisted. |
(*) What "Cloudflare blocked it" actually means
CF Free's blocks in the table above are Browser Integrity Check (error 1010) - a client TLS/JA3 fingerprint check that identifies Python, Go, Ruby, and other non-browser HTTP clients. It fires on our test harness, on some API monitoring tools, and on some legitimate integrations. It is not GraphQL depth awareness or parameter inspection.
Updated measurement 2026-05-28 (4-worker parallel test, standard HTTP client): Auth endpoint credential-stuffing: 185 req/s through CF Free, 0 blocks, all 401 from origin. REST ?limit=10000: 182 req/s through CF Free, 0 blocks, all 200 from origin. CF BIC did not fire on POST application/json or GET requests in this run. For comparison, AWS WAF Core + CloudFront: 144 req/s on auth (0 blocks), 146 req/s on REST (0 blocks). GraphQL introspection (2026-05-27): 84 req/s through CF (0 blocks), 64 req/s through AWS WAF (0 blocks), full 23KB schema returned every request. Artifacts: data/api_lab/20260528T06*_auth_credstuff.json, data/api_lab/20260528T06*_rest_limit_abuse.json, data/api_lab/20260527T*_introspection.json.
Why Traditional DDoS Protection Fails
CDN Limitations
CDNs excel at caching static content. API responses are typically:
- Dynamic (user-specific data)
- Authenticated (can't cache)
- Small but expensive (JSON payloads)
Result: Every API request passes through to your origin.
WAF Blind Spots
WAFs look for malicious payloads. API DDoS attacks use:
- Legitimate request formats
- Valid authentication tokens
- Normal-looking parameters
Result: WAF sees "valid" requests and lets them through.
Bot Detection Challenges
Browser fingerprinting doesn't work when:
- Clients are mobile apps (no browser)
- Clients are other servers (webhooks)
- JavaScript challenges break the API contract
Result: Can't distinguish automated attacks from legitimate automation.
Protecting Your APIs
1. Rate Limiting Done Right
# Good: Multi-dimensional rate limiting
rate_limit:
global: 10000/minute # Total API capacity
per_ip: 100/minute # Per source IP
per_user: 500/minute # Per authenticated user
per_endpoint:
/api/search: 10/minute # Expensive endpoint
/api/login: 5/minute # Auth endpoint
/api/export: 1/hour # Very expensive
Rate Limit Design Principle
Set limits based on the cost of the endpoint, not the expected usage. Expensive operations get stricter limits.
2. Request Validation
- Input size limits: Cap request body size (e.g., 1MB max)
- Query complexity limits: For GraphQL, limit depth and breadth
- Pagination enforcement: Max page size, require pagination
- Timeout enforcement: Kill requests that take too long
# GraphQL complexity limiting
query_complexity_limit: 1000
max_depth: 5
max_aliases: 10
introspection: disabled_in_production
3. API Gateway Protection
Deploy an API gateway that provides:
- Authentication validation at the edge
- Rate limiting before requests hit backend
- Request transformation and validation
- Circuit breakers for backend protection
- Anomaly detection across all endpoints
4. Backend Resilience
- Database connection pooling: Limit max connections
- Query timeouts: Kill slow database queries
- Async processing: Queue expensive operations
- Graceful degradation: Return cached/partial data under load
# Example: Request timeout middleware
async function withTimeout(handler, timeoutMs = 5000) {
return Promise.race([
handler(),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Request timeout')), timeoutMs)
)
]);
}
5. Monitoring and Alerting
You can't protect what you can't see. Monitor:
- Request rate per endpoint (not just total)
- Response time percentiles (P50, P95, P99)
- Error rates by type (4xx vs 5xx)
- Backend resource utilization
- Cost per request (for cloud functions)
Alert on Cost, Not Just Traffic
A slow increase in expensive queries can cost more than a spike in cheap requests. Alert when compute costs per request increase.
API Security Checklist
Use this checklist to assess your API's DDoS resilience:
- Authentication: All endpoints require authentication (except truly public ones)
- Rate Limiting: Every endpoint has appropriate limits
- Input Validation: Size limits, type checking, sanitization
- Query Complexity: GraphQL depth/cost limits enforced
- Pagination: All list endpoints paginated with max page size
- Timeouts: Request and database query timeouts configured
- Monitoring: Per-endpoint metrics with anomaly alerting
- Circuit Breakers: Backend failures don't cascade
- Documentation: Rate limits published in API docs
- Testing: Regular load testing includes API endpoints
The Business Case for API Protection
APIs often generate more revenue than websites but receive less security investment. Consider:
- API downtime = mobile app outage = lost transactions
- Partner API disruption = breach of SLA = penalties
- Resource exhaustion = cloud bill spike = margin erosion
- Slow APIs = poor user experience = customer churn
"We spend more protecting our marketing site than the APIs that process $50M in daily transactions."
- Anonymous CTO at a Series B startup
What Changes With Paid WAF Plans
The lab results above used default free-tier configurations. Paid plans add capabilities - but with an important catch.
| Capability | Cloudflare Free | Cloudflare Business ($200/mo) | Cloudflare Enterprise + API Shield | AWS WAF (any tier, custom rules) | AWS BotControl Targeted | AFD Premium (DRS 2.1) |
|---|---|---|---|---|---|---|
| Auth endpoint rate limiting | None | 10 custom rate-limit rules (can target /auth/* per IP) | Advanced rate limiting (cost-based) | Custom rate-based rule, BLOCK mode, path-scoped | Session token tracking + CAPTCHA on anomalous patterns | Custom WAF rule possible |
| REST param range validation (e.g. block limit>1000) |
None | Custom rule with query string match | Custom rule + API Shield endpoint mgmt | Custom regex rule on query string | None (behavioral, not param-based) | Custom match rule possible |
| GraphQL depth/complexity limits | None | None | API Shield add-on: depth, breadth, POST body size limits | None (app-layer control required) | None | None (custom rule possible but no depth parsing) |
| GraphQL introspection blocking | None | Custom body-match rule possible | API Shield: disable introspection | Custom body-match rule | None | Custom body-match rule |
| API schema validation (block non-schema requests) |
None | None | API Shield only (Enterprise add-on) | None | None | None |
The rule that can't be written without schema knowledge
Every capability in the "paid" column that mentions "custom rule" requires a human to write a rule that encodes what normal looks like for your API. The WAF cannot know that limit=10000 is unusual unless you told it what the maximum is. It cannot know that a GraphQL query nesting 15 levels deep is expensive unless you told it your resolver cost model. Paid plans provide the tooling to write those rules. They do not come with the rules already written.
This is why an attacker querying your GraphQL endpoint 100 times per second with valid-looking queries that traverse your most expensive resolvers does not get blocked by any managed ruleset at any price tier - the WAF has no way to distinguish that from a legitimate analytics dashboard refresh.
What actually changes at each tier (summary)
- Free to Pro/Business: You gain custom rule slots. You can now write "block more than 10 POSTs to /auth/login per IP per minute." Nothing is written for you.
- Business to Enterprise (Cloudflare): API Shield adds GraphQL depth limits and schema validation - these are the first managed rules that understand API structure. Still requires you to upload your OpenAPI/GraphQL schema.
- AWS WAF to BotControl Targeted: Adds behavioral bot detection (browser challenges, session tokens). Protects auth endpoints against scripted attacks even from browser-fingerprint-capable clients. Does not add API payload inspection.
- AFD Standard to Premium: Gains DefaultRuleSet 2.1 (web exploit signatures) and BotManagerRuleSet. No API-specific managed rules. Our gRPC lab confirmed Premium blocks
application/grpcby content-type - a protocol-level gate, not payload inspection.
Is Your API Protected?
DDactic identifies API vulnerabilities before attackers exploit them. Our automated assessment covers endpoints, rate limits, and backend resilience.
Get an API Assessment