AP-0206Spend & resource abuseSeverity · High

Metered features a stranger can spend for you

A product spends money on each request it serves: model calls, compute, storage, messages. When a metered feature is reachable outside the flow that meters it, a stranger can run up the bill and the meter never moves.

At a glance

Controls
OWASP API4:2023 · SOC 2 CC6.1 · ISO 27001 A.12.1
LikelihoodCommon where AI features are added quickly
Effort to exploitLow: script the raw endpoint
Blast radiusThe account’s or company’s cloud bill
What review catchesLittle: the happy path is metered

Every product has a unit that costs real money to serve. For AI features that unit is a model call, and it can cost a fraction of a cent or several cents each. The product meters that call inside the flow the user is meant to take. The trouble starts when the same capability is reachable by a route that skips the meter: a raw endpoint, an internal service exposed to the internet, or a prompt field that will answer anything.

Why it happens

Metering, quotas and billing are usually built around the intended path, because that is the path the team designed and demoed. The endpoint that actually does the work sits one layer beneath, and it does not know or care whether the meter above it ran. If that endpoint can be called directly, the accounting is optional. Free trials make it worse, because the cheapest way to get more free capacity is to hold more free accounts.

How the attack unfolds

An attacker finds the endpoint that performs the expensive operation and calls it in a loop, with a larger context, a longer output or a more expensive model than the interface would ever request. They spread the load across many trial accounts so no single one trips a limit. The product keeps serving, because each individual call looks like ordinary use, and the cost surfaces only when the invoice arrives.

The limit was on the button, not on the thing the button called.MATT research team

Why review misses it

The metered path works perfectly in every test, because the tests use the interface. The unmetered path is the same code reached a different way, and nobody writes a test that calls it out of context. The cost of the gap is invisible until someone is paying it.

Where it hides

What a reviewer can look for in the code and in the behaviour, before anyone proves it.

  • The endpoint that performs an expensive operation can be called without the product flow that meters it.
  • Model choice, context size or output length are taken from the request without a server-side ceiling.
  • Quotas are enforced per account but a single actor can hold many trial accounts.
  • There is no alert that fires within minutes when spend for a user or key jumps.

A real instance

A support chatbot’s underlying endpoint answered any prompt sent straight to it, at any context length. A script drove it for a weekend across a rotation of trial accounts and turned a product with a modest user base into a five-figure model bill before the Monday cost report showed it.

Details altered to protect the customer. Pattern, timing and outcome are as found.

How MATT tests it

The proof runs against the deployed product, on every release, whoever wrote the code.

  1. 01Find the endpoint behind each metered or AI feature and call it directly, outside the interface.
  2. 02Push the expensive parameters: larger context, longer output, a more costly model than the interface offers.
  3. 03Distribute the calls across many accounts and keys to test whether limits hold under spread.
  4. 04Measure how quickly a spend anomaly is noticed, from first abusive call to a human being paged.

The evidence

Before the fix
  1. POST /internal/generate (no product flow)200 OKRaw model call served, no quota consulted
  2. x200 across 40 trial accounts200 OKPer-account limits never tripped; bill climbs
After the fix
  1. POST /internal/generate (no product flow)403 ForbiddenEndpoint reachable only through the metered flow
  2. x200 across 40 trial accounts429 Too Many RequestsSpend ceiling per actor holds, anomaly pages a human
The rule, in plain English

A metered operation must be reachable only through the flow that meters it, and no account may spend beyond its plan by any route.

Executable check

Every expensive endpoint must reject a call made outside its metered flow, and a spend anomaly must page a human within fifteen minutes, on every release.

Every rule MATT holds →

What the fix looks like

  1. 01

    Meter at the expensive call

    Enforce the quota where the cost is incurred, so no route can reach the operation without accounting for it.

  2. 02

    Bound the parameters

    Cap model, context size and output length server-side, so a request cannot ask for an arbitrarily expensive answer.

  3. 03

    Alert on spend, not just usage

    A spend anomaly for any user or key must page a human within fifteen minutes.

A check that was never written is found by proving the deployed behaviour, fixed with the engineer who shipped it, and kept fixed by running the control on every change. What is ExploitOps? →

ExploitOps discovery call

Understand where your security loop breaks.

A 15-minute call with a MATT co-founder to understand your product and whether an ExploitOps Review is worth doing. If there is a real need, we scope one with the research team.