Unrestricted Resource Consumption happens when an API lets a caller spend the provider's CPU, memory, storage, bandwidth or paid third-party services without a limit that matches what the operation actually costs. OWASP ranks it fourth in the API Security Top 10 2023, and the 2023 edition widened the old "lack of resources and rate limiting" item to include money: per-request SMS, email and biometric fees, and cloud bills, not only outages. This guide goes deeper than the overview in the Top 10 API Security Risks. It sets out what OWASP says makes an API vulnerable, how to design limits in layers, how to key quotas to the right identity, how to test and evidence the controls, and how API4 maps to ASVS 5.0, NIST and ATT&CK. It is written for API developers, platform engineers, application security teams and cloud budget owners.
Key takeaways
- Rate limiting alone is not the fix. OWASP lists eight limits (timeouts, memory, file descriptors, processes, upload size, operations per request, records per page, third-party spending), and a gap in any one of them makes the API vulnerable.
- Cost per request matters more than request count. One GraphQL call can carry hundreds of mutations, and one "forgot password" call can trigger a paid SMS; limits must count the expensive unit, not the HTTP request.
- Quotas belong to identities, not IP addresses. Key limits to the authenticated client, user, tenant and API key, then add IP-based limits only for unauthenticated endpoints.
- Spending caps are a security control. OWASP explicitly requires spending limits on every service provider integration, or billing alerts where a hard cap is not offered.
- Fail closed and tell the caller. Reject over-limit work early with 413, 429 or 431, return Retry-After where it helps, and log every rejection with the identity that caused it.
What it is and who it applies to
OWASP's official entry is API4:2023 Unrestricted Resource Consumption. Its risk rating is: exploitability Average, prevalence Widespread, detectability Easy, technical impact Severe. OWASP notes that exploitation needs nothing more than simple API requests, sent concurrently from one computer or from rented cloud capacity, and that attackers can infer the cost impact from the provider's public pricing model even without seeing the bill.
The impact has two halves. The first is availability: resource starvation leads to denial of service. The second is financial: higher CPU demand, growing storage, egress charges and pay-per-call integrations raise operating cost, sometimes faster than anyone notices. OWASP's third example scenario is a file download service whose cache only held objects up to 15 GB; when one file grew to 18 GB, every client pulled it from origin storage and the monthly bill rose from about US$13 to US$8,000, because there were no cost alerts and no maximum allowance.
API4 applies to any API, internal or public, REST, GraphQL, gRPC or SOAP. It is most acute for:
- APIs that call paid services: SMS and voice OTP, email, identity verification, biometrics, mapping, LLM inference. For model-specific limits, see the OWASP LLM10 unbounded consumption guide.
- APIs with flexible queries: GraphQL, OData and search endpoints where the caller controls depth, filters and page size.
- Heavy processing endpoints: image and video transcoding, PDF rendering, report generation, archive extraction, exports.
- Serverless and autoscaling back ends: they rarely fall over under load; instead they scale and send the bill. The Denial-of-Wallet and AI Agent Cost Runaway Guide covers this cost-first failure mode for AI workloads.
API4 sits next to API6. API4 is about the cost of individual operations; API6 is about legitimate business flows (buying, booking, signing up) abused at scale even when each request is cheap. Many controls overlap, but the analysis starts in a different place.
Structure and key requirements
OWASP's "Is the API vulnerable?" test is a list of limits. The API is vulnerable if at least one is missing or set inappropriately, either too high to protect or too low to serve real users. The table turns each into an engineering requirement.
| OWASP limit | What to set | Where it is usually enforced | Typical over-limit response |
|---|---|---|---|
| Execution timeouts | Per-request and per-resolver deadlines, plus short timeouts on outbound calls | Application code, gateway, load balancer | 503 or 504, work cancelled |
| Maximum allocable memory | Container or function memory ceiling | Runtime (container limits, serverless memory setting) | Process killed and restarted |
| Maximum file descriptors | ulimit or equivalent per process | Container runtime, OS | Connection refused |
| Maximum number of processes | PID and worker limits | Container runtime, process manager | Fork refused |
| Maximum upload file size | Body size cap, plus uncompressed size and file count for archives | Gateway, web server, application | 413 Content Too Large |
| Operations per request | Batch size, GraphQL aliases and mutations per document, bulk endpoint item count | Application (GraphQL server, bulk handler) | 400 with a clear error |
| Records per page | Server-side maximum for limit, page_size, first or top parameters | Application and data layer | Clamp to maximum or 400 |
| Third-party spending limit | Hard cap per provider account, per day and per month; alerts below the cap | Provider console or API, cloud budgets | Provider rejects calls; your API degrades gracefully |
The OWASP prevention list adds the controls that tie these together:
- Use a platform that makes limits easy: containers and serverless functions, where memory, CPU, restarts, file descriptors and processes are configuration, not code.
- Cap every input: maximum string length, maximum array elements and maximum upload size on all parameters and payloads, whether the file lands locally or in cloud storage.
- Rate limit, tuned to the business: some endpoints need much stricter policies than others.
- Throttle single operations per client: OWASP names validating an OTP and requesting password recovery as examples.
- Validate the parameters that control result size: server-side, not only in the client.
- Configure spending limits for every provider and integration: billing alerts where caps are not possible.
GraphQL needs its own limits
OWASP's second scenario shows why: an API had rate limiting and an image size check, but one HTTP request containing 999 uploadPic mutations exhausted server memory. The OWASP GraphQL Cheat Sheet sets out the GraphQL-specific controls: depth limiting (depth is unlimited by default), amount limiting on list arguments such as first, query cost analysis that assigns a cost to fields and rejects documents over a maximum, application-level timeouts on queries and resolvers (its examples use 10 seconds), and batching controls that count objects requested rather than HTTP requests. ASVS 5.0 requirement V4.3.1 makes this verifiable: a query allowlist, depth limiting, amount limiting or query cost analysis must prevent expensive nested queries. See the GraphQL Security Guide.
Choosing a rate limiting model
| Model | Behaviour | Good for | Watch out for |
|---|---|---|---|
| Token bucket (rate plus burst) | Tokens refill at a steady rate; burst is bucket capacity | General API traffic with short spikes; used by major cloud gateways | Burst too large lets a client spend a full bucket on expensive calls |
| Fixed window counter | N requests per calendar minute or hour | Simple quotas, billing tiers | Double traffic at window edges |
| Sliding window | Counts requests in the trailing interval | Login, OTP and recovery endpoints | More state per key |
| Concurrency limit | Maximum in-flight requests per key | Slow, heavy endpoints (exports, rendering) | Needs reliable release on timeout |
| Cost-based quota | Each call spends units weighted by cost (query cost, tokens, SMS) | GraphQL, LLM and paid-integration endpoints | Needs a cost model that is maintained as the API changes |
Two cautions from vendor documentation apply generally. AWS documents that API Gateway throttles and quotas are applied on a best-effort basis and "should be thought of as targets rather than guaranteed request ceilings", so a gateway limit is a first layer, not the only one. And the HTTP semantics are standard: RFC 6585 defines 429 Too Many Requests, which may carry a Retry-After header and must not be cached, and 431 Request Header Fields Too Large. The IETF RateLimit header fields are still an Internet-Draft, so treat them as optional.
For algorithm detail and gateway configuration, see the Rate Limiting and API Abuse Guide and the API Gateway Security Guide.
Identity and NHI requirements
A limit is only as good as the key it counts against. Most API traffic today comes from non-human callers: mobile apps, partner integrations, service accounts, CI jobs and AI agents. That makes API4 an identity problem as much as a capacity one.
- Key quotas to the authenticated principal: client ID, API key or workload identity first, then user and tenant. IP addresses change, are shared behind NAT and are cheap to rotate; ASVS 5.0 V15.3.4 also warns that the client IP must come from trusted proxy fields and may still be unreliable.
- Layer the keys: per credential (stops one leaked key draining the tenant), per tenant (stops one customer starving others), per operation (stops one expensive endpoint consuming the whole allowance) and global (protects the platform).
- Do not treat API keys as authentication: AWS describes usage-plan API keys as client identifiers for throttling, not authorisation. Pair them with OAuth client credentials, mTLS or workload identity. See the API Key Management Guide.
- Cap your own outbound credentials: the keys your API uses to call SMS, email and LLM providers are NHIs with a spending power. Give each its own provider account or project, its own cap and its own alert, so a bug or abuse in one feature cannot spend the whole budget.
- Assume stolen keys will be used to maximise spend: in the LLMjacking campaigns, attackers used stolen cloud credentials and leaked keys to run inference on the victim's account, and researchers estimated potential costs above US$46,000 per day; budget alarms were among the fastest detectors. See the LLMjacking Guide.
- Give AI agents explicit budgets: an agent that loops or fans out tool calls is a high-volume API client. Issue it its own identity and quota rather than letting it share a human user's or a service's allowance.
For the wider picture of machine credentials, see the Non-Human Identity (NHI) Guide.
Implementation steps
- Inventory expensive operations. For every endpoint, record the unit of cost: CPU seconds, memory, bytes stored or sent, rows scanned, third-party calls and their price. ASVS 5.0 V15.1.3 requires documentation to identify time-consuming or resource-demanding functionality and how to prevent loss of availability from it.
- Set runtime ceilings. Apply memory and CPU limits to containers or functions, maximum concurrency on serverless functions, and in Kubernetes a namespace ResourceQuota with a LimitRange supplying defaults so no pod runs unbounded.
- Cap inputs at the edge and in code. Body size at the gateway and web server; string, array, page size and batch size in the schema (OpenAPI
maxLength,maxItems,maximum) and enforced by validation, since a spec value does nothing unless validated. For uploads, also cap uncompressed size, file count and image pixel dimensions (ASVS V5.2.1, V5.2.3, V5.2.6). - Add identity-keyed rate limits and quotas. Start in log-only or "count" mode for two to four weeks, measure the 99th percentile per client and operation, then enforce at a margin above it. Apply stricter limits to OTP send and verify, password recovery and sign-up.
- Add cost-aware limits where a request can carry many operations. GraphQL depth, amount and cost limits; bulk endpoint item caps; LLM token quotas keyed to the caller.
- Bound outbound work. Short timeouts, limited retries with back-off and circuit breakers on every downstream call (ASVS V13.1.3, V16.5.2), so a slow dependency does not tie up every worker.
- Set provider spending caps and budget actions. Configure hard caps where the provider supports them. Cloud budgets mostly alert; AWS Budgets actions can apply a deny IAM policy or SCP, or stop specific EC2 and RDS instances, at a threshold, which is closer to a cap.
- Return clear errors and degrade gracefully. 413, 429 and 431 with a Retry-After where a retry makes sense; queue heavy jobs asynchronously rather than holding connections.
- Load test the limits. Run a test that deliberately exceeds each limit in a staging environment, including a batched GraphQL request and a large upload, and confirm rejection happens before the expensive work starts.
- Plan rollback. Keep limits in configuration with per-client overrides, so a limit that blocks a legitimate partner can be raised in minutes without a deployment, and record every override with an owner and expiry.
Small team or large platform
Small teams get most of the value from managed defaults: gateway rate limits per API key, serverless memory and concurrency caps, a body size limit, a page size maximum and a provider spending cap with alerts. Large platforms need cost-based quotas per tenant, a distributed limiter with shared state, per-operation limits generated from the API specification, and a FinOps feed into the SOC so cost anomalies are triaged like security events.
Evidence and assessment
Assessors and testers should expect evidence for each OWASP limit, not a single "we rate limit" statement.
| Control | Evidence to collect | How to test |
|---|---|---|
| Payload and parameter caps | OpenAPI or GraphQL schema with limits; gateway body size configuration | Send oversized strings, arrays and bodies; expect 400 or 413 before processing |
| Page size limit | Server-side maximum in code or schema | Request page_size=100000; expect clamp or rejection |
| Batching and GraphQL limits | Depth, amount and cost settings; batching disabled or capped | Send one request with many aliased operations; expect rejection |
| Rate limits and quotas | Policy per identity and operation; 429 counts in logs | Exceed the limit with one key, then confirm a second key is unaffected |
| Runtime ceilings | Container limits, function memory and concurrency, ResourceQuota objects | Configuration review; controlled load test in staging |
| Spending limits | Provider caps, budget alerts and actions, alert recipients | Review thresholds against normal monthly spend; confirm alerts reach an owner |
| Logging | Rejections logged with identity, endpoint and limit name | Trigger each limit and find the event in the SIEM |
The API Penetration Testing Guide covers scoping these tests safely; resource tests belong in staging or in an agreed window, never as an unannounced load test on production.
Detection and metrics
- 429 and 413 rate per identity: a sudden rise for one key signals abuse or a broken client.
- Cost per tenant per day: compute, egress and third-party charges attributed to the caller.
- Third-party spend versus forecast: SMS, email and LLM spend by provider, with an alert at a fixed percentage over forecast.
- Response size and latency outliers: p99 response bytes and duration per endpoint.
- OTP send to verify ratio: many sends with few verifies is the classic sign of SMS cost abuse.
- Endpoints with documented limits: a coverage metric for the programme.
Mapping to other frameworks
| Framework | Reference | Relevance to API4 |
|---|---|---|
| OWASP ASVS 5.0 | V2.4.1, V4.3.1, V5.2.1, V5.2.3, V5.2.4, V13.1.3, V15.1.3, V15.2.2 | Anti-automation against quota exhaustion and costly resources; GraphQL DoS limits; upload size and archive limits; per-user file quota; outbound timeouts and retries; documenting and defending resource-demanding functions |
| MITRE CWE | CWE-770, CWE-400, CWE-799 | Allocation without limits or throttling; uncontrolled resource consumption; improper control of interaction frequency (the CWEs OWASP cites) |
| MITRE CAPEC | CAPEC-125, CAPEC-130 | Flooding; excessive allocation |
| MITRE ATT&CK v20 | T1499.003, T1499.004, T1496.004 | Application exhaustion flood; application or system exploitation; cloud service hijacking (spending the victim's paid services) |
| NIST SP 800-53 Rev 5 | SC-5, SC-6, SI-10, SI-4 | Denial-of-service protection; resource availability; input validation; system monitoring |
| NIST CSF 2.0 | PR.IR-04, PR.PS-06, DE.CM-09 | Adequate resource capacity; secure development; monitoring of runtime environments |
| ISO/IEC 27001:2022 Annex A | 8.6, 8.16, 8.26, 8.28 | Capacity management; monitoring activities; application security requirements; secure coding |
| CIS Controls v8.1 | Control 16 | Application software security |
For DDoS at the network layer, which API4 does not cover, see the DDoS Protection Guide. For how ASVS is structured, see the OWASP ASVS Guide.
Common pitfalls
- Counting HTTP requests, not work: the OWASP GraphQL scenario had rate limiting and still fell over to one batched request. Count operations, objects or cost units.
- Keying limits only to IP address: distributed clients and cloud-hosted attackers rotate IPs cheaply, while legitimate users behind one corporate NAT get blocked together.
- Trusting the client's page size: a mobile app that always asks for 20 records does not stop a script asking for a million. Enforce the maximum server-side.
- Uncapped paid integrations: OWASP's first scenario, a script calling "forgot password" tens of thousands of times at US$0.05 per SMS, is cheap to run and expensive to receive. Cap the provider account and rate limit the trigger per phone number and per client.
- Relying on autoscaling as the defence: autoscaling converts a denial of service into a denial of wallet. Set maximum instance counts and function concurrency.
- Budget alerts nobody reads: alerts sent to a finance mailbox monthly do not detect abuse running for hours. Route cost anomalies to an on-call owner, as the LLMjacking victims learned.
Practitioner checklist
- Every endpoint has a documented cost unit and an owner for its limits.
- Containers and functions have memory, CPU, concurrency and maximum instance limits.
- All strings, arrays, uploads, archives and page sizes have server-side maximums enforced by validation.
- GraphQL has depth, amount and cost limits, and batching is disabled or capped for sensitive operations.
- Rate limits and quotas are keyed to client, credential, tenant and operation, with IP limits only for unauthenticated calls.
- OTP, password recovery and sign-up have stricter per-target and per-client throttles.
- Outbound calls have short timeouts, bounded retries with back-off and circuit breakers.
- Every third-party provider account has a hard spending cap or, where not possible, a billing alert routed to on-call.
- Limit rejections are logged with identity and limit name, and 429 and cost anomalies are on a dashboard.
- Limits are tested in staging before release and can be overridden per client without a deployment.
Standards and references
- OWASP: API4:2023 Unrestricted Resource Consumption
- OWASP: API Security Top 10 2023
- OWASP: Application Security Verification Standard 5.0
- OWASP Cheat Sheet Series: GraphQL
- OWASP Cheat Sheet Series: Web Service Security
- IETF: RFC 6585 Additional HTTP Status Codes
- MITRE: CWE-770 Allocation of Resources Without Limits or Throttling
- AWS: Throttle requests to your REST APIs in API Gateway
Related NHI Mgmt Group resources: Top 10 API Security Risks · Rate Limiting and API Abuse Guide · Denial-of-Wallet and AI Agent Cost Runaway Guide · GraphQL Security Guide · OWASP API Top 10 API6 Unrestricted Access to Sensitive Business Flows Guide