Skip to content

All lessons

Area 06 // AI SecurityLesson 105 / 14013 min read

Denial of wallet and cost abuse

Denial of wallet is an attack (or accident) that makes your AI system spend huge amounts of money, through floods of requests, giant prompts, very long outputs, runaway agent loops or stolen keys, and you stop it with input limits, output caps, per-user budgets, rate limits and spending alerts.

Think of it like this

Analogy

A restaurant offers free refills. Most customers have one or two. Then a group shows up with buckets. The restaurant doesn't close, but it's losing money on every bucket. So it keeps the offer and adds rules: refills at the counter, one cup per customer, a sign saying "within reason", and a manager who notices buckets.

The problem it solves

Traditional denial-of-service attacks try to knock you offline. With LLMs, attackers don't need to: every request costs you money, so scripted floods of long prompts, requests for enormous outputs, prompts that trigger long reasoning, or a public endpoint resold as "free GPT" can quietly run up thousands per day. Bugs do the same: an agent loop, a retry storm, a test script left running. OWASP calls this unbounded consumption (LLM06, as of November 2026).

How it works, step by step

  1. Know the attack vectors: request floods; maximum-size inputs; prompts asking for very long outputs or heavy reasoning; triggering expensive tools or agent loops; mass free-account signups; stolen or leaked keys (secrets); attackers reselling access to your endpoint.
  2. Require identity: authentication for anything costly; CAPTCHA or verification for free signups; per-account, not just per-IP, limits.
  3. Cap each request: maximum input size (reject at the edge, before any model call), max_tokens on every call, limits on reasoning effort or thinking budget, timeouts (token budgets).
  4. Cap each task: step, tool-call and cost limits for agents (stop conditions).
  5. Cap each user and tenant: requests per minute and a daily token or dollar budget (rate limiting, multi-tenancy).
  6. Cap the whole system: provider spending limits per key, separate keys per feature, budgets in your gateway.
  7. Monitor and alert: cost per user, per feature and per hour; alerts on spikes against the normal pattern; anomaly detection on usage (latency and cost metrics).
  8. Have a kill switch: feature flags to disable or downgrade a feature (to a cheaper model, or off) in seconds.
Limits at every level bound the worst case.

See it in code

Needs
Nothing: plain Python 3. Example prices as of November 2026 (mid-tier $2/$10 per 1M tokens).

One free account sends 10,000 large requests asking for very long answers, with and without limits.

denial_of_wallet.py
# Denial of wallet: an attacker scripts thousands of huge requests to run up YOUR model bill.
PRICE_IN, PRICE_OUT = 2.00, 10.00                 # $ per 1M tokens (example, Nov 2026)
LIMITS = {"max_input_tokens": 8_000, "max_tokens": 800, "daily_budget_usd": 2.00}
 
def cost(inp, out):
    return inp / 1e6 * PRICE_IN + out / 1e6 * PRICE_OUT
 
def run_attack(requests: int, inp: int, out: int, protected: bool) -> str:
    spent, served = 0.0, 0
    for _ in range(requests):
        if protected:
            if inp > LIMITS["max_input_tokens"]:
                break                              # rejected at the edge, costs nothing
            out = min(out, LIMITS["max_tokens"])
            if spent + cost(inp, out) > LIMITS["daily_budget_usd"]:
                break                              # per-user daily budget reached: 429 until tomorrow
        spent += cost(inp, out)
        served += 1
    return f"served {served:,} requests, cost ${spent:,.2f}"
 
# 10,000 requests of 7,000 input tokens asking for 4,000-token answers from ONE free account:
print("no limits  :", run_attack(10_000, 7_000, 4_000, protected=False))
print("with limits:", run_attack(10_000, 7_000, 4_000, protected=True))
Output
no limits  : served 10,000 requests, cost $540.00
with limits: served 90 requests, cost $1.98

$540 from one account in one day; a hundred scripted accounts is $54,000. With limits, each account's worst case is $2 a day, and sign-up verification limits how many accounts an attacker can make.

A real example

Example

The free tier that became someone else's product

A startup launched a free AI writing tool with no login. Within two weeks, someone had wrapped its API endpoint into their own paid app, sending a quarter of a million requests a day. The bill went from $300 to $11,000 a week before anyone noticed.

The fix: login required, email verification, per-account daily budgets, a 4,000-character input cap, max_tokens of 1,000, origin checks plus short-lived session tokens on the API, a spending alert at twice the normal hourly rate, and a feature flag to switch the free tier to a small model during abuse. Costs dropped back within a day.

The easy way

Start here

Set max_tokens on every call, cap input size, require login for anything costly, add a per-user daily budget, and turn on your provider's spending limit and alerts. Those five steps stop almost all accidental and casual abuse.

When you grow: the production setup

Teams enforce budgets in a gateway at user, tenant, feature and key level; detect anomalies on cost per account; use bot protection on signups; separate keys per feature with caps; enforce agent cost ceilings; run cost-abuse cases in red-team suites; and keep a tested kill switch and downgrade path.

Trade-offs

What you gain

  • Bounds the worst-case bill.
  • Protects capacity for legitimate users.
  • Makes costs predictable for pricing.

What it costs you

  • Limits can frustrate heavy legitimate users.
  • More friction at signup.
  • Budgets need tuning per plan and feature.

When not to use it

  • Never run a public AI feature without limits; internal tools still need at least max_tokens and spending alerts.

Common mistakes

  • No max_tokens, so a single request can produce a huge, costly answer.
  • Rate limiting by IP only, which bots easily rotate.
  • No spending alerts until the monthly invoice.
  • Agent loops without step or cost ceilings.
  • Public, unauthenticated endpoints calling expensive models.

Interview questions

Try answering out loud first, then open the model answer.

What is denial of wallet and how do you prevent it?

Model answer

An attack or failure that drives up resource costs instead of causing downtime, e.g. floods of large requests, long outputs, agent loops or stolen keys. Prevent it with authentication and signup verification, per-request caps (input size, max_tokens, timeouts), per-task agent limits, per-user and per-tenant rate limits and budgets, provider spending caps per key, cost monitoring with anomaly alerts, and a kill switch.

How would you protect a free tier of an AI product?

Model answer

Require accounts with verification, apply tight per-account daily budgets and rate limits, cap input and output sizes, route to a cheaper model, use bot detection, protect the API from being called by third-party apps (short-lived session tokens, origin checks), monitor per-account cost, and have a downgrade switch for abuse spikes.

Why are reasoning models and agents a bigger cost-abuse risk?

Model answer

A single request can trigger long hidden reasoning or many steps of tool calls, each resending large contexts, so the cost per request is high and variable. An attacker can craft inputs that maximise reasoning or loops. Limit reasoning budgets, steps and total cost per task, and monitor cost per request.

Quiz

Pick an answer to see whether it’s right and why.

  1. 01What is denial of wallet?
  2. 02Which control limits the cost of each individual response?
  3. 03An agent got stuck in a loop overnight. What would have stopped it?
  4. 04Why set per-user daily budgets on a free tier?
  5. 05Which OWASP 2026 risk covers this?

0 of 5 answered

Key terms

Denial of wallet
An attack or accident that makes a system spend large amounts of money (for example on model calls) instead of making it unavailable.
Unbounded consumption
An AI system using resources or money without limits, through floods of requests, huge prompts, long outputs or runaway agents. LLM06 in the OWASP 2026 list.
Rate limit
A cap on how many requests or tokens a client may send in a period. Providers return HTTP 429 when you exceed theirs.
Token budget
A limit on how many tokens a request, step or whole task may use, to control cost, latency and context size.
Spending alert
An automatic warning when costs for a key, feature or account go above a set level or rise unusually fast.

Before and after

Progress is saved in this browser only.