๐ What Is It?
Unbounded Consumption occurs when an app lets clients drive a model to perform inference โ and spend compute, memory, time, and money โ without effective limits. The 2025 edition merges the old Model DoS and Model Theft entries: both share one root cause, inference proceeding without bounds. Exploitation needs no jailbreak and often no authentication โ only the ability to send requests. LLM economics make it potent: a short prompt can command an enormous, expensive response (asymmetric cost), and transformer attention scales roughly with the square of sequence length (superlinear).
LLM10
OWASP Rank 2025
Merged
Model DoS + Model Theft
3 Harms
DoS ยท DoW ยท Theft
โ๏ธ Three Harm Axes
- Denial of Service (DoS): resource exhaustion degrades/halts the service for real users.
- Denial of Wallet (DoW): on metered/autoscaling infra the attack wins even while the service stays up โ it just generates a ruinous bill.
- Model theft / extraction: unlimited querying lets an attacker distill a "student" clone or infer training-data facts โ no weight file stolen.
โ ๏ธ Top Attack Vectors
- Long-input / context stuffing: few requests, each a max-length prompt โ superlinear GPU cost.
- Unbounded output: "count to 1,000,000",
max_tokens: null. - Agentic fan-out: one request spawns thousands of sub-agent inferences.
- Sponge examples: inputs crafted for worst-case compute; defeat request-count limits.
- Concurrency abuse: stay under req/min but fire all in parallel to saturate workers.
- Model extraction: harvest I/O pairs at scale to train a functional clone.
๐ด Attack Flow
1. Recon โ probe the endpoint: which limits exist (size? max_tokens? rate? auth?)
โ
2. Pick a lever โ the unbounded dimension with the best cost-amplification ratio
โ
3. Amplify โ volume ร cost-per-request ร concurrency
โ
4. Evade โ spread across keys/IPs, or make few requests maximally expensive
โ
5. IMPACT: outage (DoS), ruinous bill (DoW), or a model clone (Theft)!
โ
2. Pick a lever โ the unbounded dimension with the best cost-amplification ratio
โ
3. Amplify โ volume ร cost-per-request ร concurrency
โ
4. Evade โ spread across keys/IPs, or make few requests maximally expensive
โ
5. IMPACT: outage (DoS), ruinous bill (DoW), or a model clone (Theft)!
โ Vulnerable Code (FastAPI gateway)
class ChatIn(BaseModel):
message: str # no length bound
history: list[str] = [] # unbounded conversation
max_tokens: int | None = None # client controls output length
@app.post("/api/chat")
async def chat(body: ChatIn):
prompt = "\n".join(body.history + [body.message]) # arbitrary size
# No auth, no token check, no output cap, no timeout, no cost budget
return await model.generate(prompt, max_tokens=body.max_tokens)
โ Secure Code (bounded gateway)
MAX_INPUT_TOKENS = 4_000; SERVER_MAX_OUTPUT_TOKENS = 1_024
class ChatIn(BaseModel):
message: str = Field(max_length=8_000) # hard string bound
history: list[str] = Field(default=[], max_length=20) # bound history
max_tokens: int | None = Field(default=None, ge=1, le=1_024)
@app.post("/api/chat")
async def chat(body: ChatIn, identity: str = Depends(current_identity)):
await rate_limit(identity) # per-identity, not IP
prompt = "\n".join(body.history[-20:] + [body.message])
if count_tokens(prompt) > MAX_INPUT_TOKENS: # token cap = cost cap
raise HTTPException(413, "Input exceeds token limit")
max_out = min(body.max_tokens or 512, SERVER_MAX_OUTPUT_TOKENS) # clamp
if not await reserve_budget(tenant_of(identity), max_out): # DoW guard
raise HTTPException(402, "Daily budget exhausted")
return await model.generate(prompt, max_tokens=max_out, timeout=30)
โ Prevention Checklist
- Cap input size โ byte cap at the edge and token count on the whole prompt (history + RAG)
- Server-enforced
max_tokenson every generation; clamp the client's value, never trust it - Rate limit per identity (user/key/tenant), not just per IP
- Token and spend quotas โ request count alone doesn't bound cost
- Cap concurrency (per-identity and global); timeouts + circuit breaker on every call
- Per-tenant cost budget checked before the call, behind a provider hard billing cap
- Bound agent/tool fan-out: hard step, depth, and shared-token budgets
- Require auth so usage is attributable and boundable per identity
- Meter actual tokens/cost; detect extraction sweeps; withhold logprobs from untrusted callers
- Degrade gracefully โ shed load with clear 429/402/503, never collapse or overspend
๐งฐ Tools & Takeaway
tiktoken
Redis rate limit
API gateway
Billing caps
Budget alerts
Anomaly detection
Watermarking
๐ก Takeaway: Bound every dimension of cost โ input tokens, output tokens, request rate, concurrency, and money โ not just request count. Treat cost budgets and billing caps as security controls, and enforce everything server-side at a gateway the client cannot bypass.
โ ๏ธ Autoscaling is not a defence: it protects availability and thereby converts a DoS into a Denial of Wallet โ you pay to serve the attack. The first signal is often the invoice, not an outage.