The arithmetic of one script
An endpoint with no authentication that forwards text to a frontier model. An attacker’s script sends ten requests a second, each with a 4,000-token prompt and asking for a 1,000-token reply. Input: 40,000 tokens a second, around $0.12 at $3 per million, which is about $430 an hour. Output: 10,000 tokens a second, around $0.15 at $15 per million, about $540 an hour. Call it a thousand dollars an hour, twenty-four thousand a day, from one machine with no skill required, and the provider will bill you for every token because every request was valid.
This is not hypothetical. Free-tier “try it” boxes on product pages have been discovered by people running scripts within days of launch, and the bill arrives before the discovery.
Where the bill is exposed
- An endpoint reachable without a login.
- A login with no per-user budget, so one account with a script is enough.
- A generous
max_tokenson every request. - No cap on input length, so a single request can carry a hundred thousand tokens of pasted text.
- An agent loop without the three budgets from the loop lesson: the commonest “attacker” is your own misconfigured loop.
- A retry policy without backoff, which the first module showed will attack your own bill during an outage.
- A free trial generous enough to be worth signing up for a thousand times.
The defences, in layers
Authentication before the model. No anonymous request reaches a paid call. Where a feature must be open to visitors, put a bot check at the edge (Cloudflare Turnstile and hCaptcha are free) and issue a short-lived token before the first model call. That is exactly how this site gates guest posting.
A per-user budget, claimed before the call. Each user has a daily allowance in tokens or in requests. Before calling the model, increment a counter with an expiry (a Redis INCR with a TTL, or a per-user object in a serverless store) and refuse if it is over. Claim before, not after: two hundred requests fired in parallel all pass an “after” check because none has been counted yet, and all two hundred run. Refund the claim if the provider call fails, so an outage does not eat a user’s allowance. This site’s own AI feature does precisely this: quota claimed last, refunded on provider failure.
Rate limits by IP and globally. Token buckets per address catch one machine; a global ceiling on requests per minute catches a distributed one. Fail closed on the global limit: better a few minutes of refusals than a night of spend.
Caps on both ends. A maximum input length in characters, enforced before tokenisation, and a max_tokens per tier. A guest gets a small model and a short reply.
A spend alert and a kill switch. Set a daily budget at the provider with an alert, and add an environment flag that disables the feature in seconds without a deployment. A kill switch that requires a deploy is not a kill switch at three in the morning.
Watch the distribution. From the traces, compute cost per user per day. If the top ten users are a third of the spend, look at who they are. Alert when a new account enters the top one per cent within its first hour; that is the signature of a script.
Tiers are budgets
Map allowances to the identity ladder: a visitor gets a handful of calls on the cheapest model, a member gets more, a verified account more again, a paying customer is metered against what they pay. The cheaper model for lower tiers is not only about cost; it lowers the reward for abusing the tier.
Caching is also a defence
The repeat attack (the same prompt ten thousand times) is served from a response cache at no cost once the first response is stored, and the later module on caching covers the mechanics. A cache keyed on the exact prompt turns the simplest attack into a free one for you.
The trial trap
A free trial with a month of generous limits attracts sign-ups from scripts, each with a disposable email. Either make the trial small enough not to be worth the effort, or require something scarce (a phone number, a card that is not charged) before the paid model is reachable. Weigh that against the friction it adds for real people; the answer depends on how much a trial can cost you, which the arithmetic at the top of this lesson tells you.
Every lesson here is open. Your progress is recorded once you pass the Python, from Zero, for AI exam.
Check your understanding
A per-user daily budget is enforced by counting a request after the model call returns. A user fires 300 requests at once and all of them run. Why?
Pick the one you would defend. Your answer stays private.
Stuck on something?Ask Sayali, your AI tutor