DEV Community

Cover image for A 256-Token Prompt Just Became a $0.58 Bomb. Here's the Fix.
Assili Salim
Assili Salim

Posted on

A 256-Token Prompt Just Became a $0.58 Bomb. Here's the Fix.

I was reading through the CCS 2026 accepted papers when one stopped me cold.

The paper is called ReasoningBomb.

The premise: craft a prompt short enough to look completely harmless — under 256 tokens — and it drives a reasoning model into a pathologically long chain of thought. Not occasionally. Consistently. Across commercial models. With a 286.7× input-to-output amplification ratio and a 98.4% bypass rate against dual-stage detection systems built specifically to catch it.

The security community is calling this a DoS attack. That framing is correct.

But there's a second attack happening at the same time that nobody's writing about: the financial one.


Run the math. It's worse than you think.

GPT-5.6 Sol pricing: $5/M input, $30/M output. Reasoning tokens bill as output.

One triggered call:

Input:   256 tokens  × $5/M   =  $0.00128
Output: 19,263 tokens × $30/M =  $0.57789
Total:                          $0.579 per call
Enter fullscreen mode Exit fullscreen mode

452× cost amplification. On a single request. Not because the model failed — because it succeeded at generating the longest possible reasoning trace.

On Claude Opus 4.8 ($15/$75 per million): $1.44 per triggered call.

Now think about what your agent processes every day. Customer support tickets. Document ingestion. Code review tools reading PR descriptions. Web browsing agents fetching arbitrary URLs. Any external content flowing through a reasoning model on metered API is a potential trigger surface.

The attack doesn't need a malicious user at a keyboard. A crafted document in your RAG pipeline, a poisoned page your agent scrapes, a tampered issue in your ticketing system — all of them can carry it.


Why your existing controls won't catch this

Rate limits cap requests per minute, not cost per request. ReasoningBomb firing once a minute is fully within rate limits — billing $0.578 per call, continuously.

Spending alerts fire after the cost is incurred. By the time your 80% budget alert triggers, the session is already over budget. The alert is accurate and completely useless.

Monthly caps — you find out next month.

No max_completion_tokens set — most frameworks don't set this by default on reasoning models. The model decides how long to think. The attack exploits exactly this gap.


The only intervention point that matters: before the call

Two defenses. They work best together.

First: always set max_completion_tokens on reasoning model calls.

This is the minimum viable defense. Set a ceiling that covers your legitimate use cases — with room to spare, but not 19,000 tokens of room:

const response = await openai.chat.completions.create({
  model: 'gpt-5.6-sol',
  messages: [{ role: 'user', content: userInput }],
  max_completion_tokens: 2000, // hard ceiling — tune for your task
});
Enter fullscreen mode Exit fullscreen mode

A task that legitimately needs 800 output tokens isn't affected by a 2,000-token ceiling. A ReasoningBomb trying to generate 19,263 tokens gets cut off at 2,000 — and your bill reflects that, not the attack's intent.

Second: make the ceiling dynamic based on remaining session budget.

A static ceiling protects individual calls. A budget-aware ceiling protects the entire session:

const MODEL_PRICES: Record<string, { inputPerM: number; outputPerM: number }> = {
  'gpt-5.6-sol':     { inputPerM: 5.00,  outputPerM: 30.00 },
  'gpt-5.6-terra':   { inputPerM: 2.00,  outputPerM: 12.00 },
  'gpt-5.6-luna':    { inputPerM: 0.20,  outputPerM:  1.20 },
  'claude-opus-4-8': { inputPerM: 15.00, outputPerM: 75.00 },
};

function guardWithOutputCeiling(
  model: string,
  session: { spentCents: number; reservedCents: number; limitCents: number }
): number {
  const price = MODEL_PRICES[model];
  if (!price) throw new Error(`Unregistered model: "${model}"`);

  const remainingCents =
    session.limitCents - session.spentCents - session.reservedCents;

  if (remainingCents <= 0) {
    throw new Error(`Session budget exhausted`);
  }

  const affordableTokens = Math.floor(
    (remainingCents / 100 / price.outputPerM) * 1_000_000
  );

  const TASK_MAX_OUTPUT = 4_000;
  return Math.min(affordableTokens, TASK_MAX_OUTPUT);
}

// Before every reasoning model call:
const maxTokens = guardWithOutputCeiling('gpt-5.6-sol', session);

const response = await openai.chat.completions.create({
  model: 'gpt-5.6-sol',
  messages,
  max_completion_tokens: maxTokens,
});
Enter fullscreen mode Exit fullscreen mode

What this does: a ReasoningBomb targeting a session with $0.10 remaining gets capped at 3,333 output tokens — the maximum $0.10 buys at Sol pricing.

The attack still fires. But its cost is bounded by what the session can actually afford — not by what the attack is trying to spend.

That's the distinction that matters: "attack succeeded" versus "attack controlled your bill." The ceiling doesn't prevent the trigger. It prevents the trigger from determining the cost.


The threat model to carry into production

ReasoningBomb isn't a theoretical edge case. It's accepted at a top-tier security conference. The code is published on GitHub. It achieves near-perfect detection bypass on commercial models including GPT-5.6.

Any agent processing external content through a reasoning model on metered API is currently exposed.

The fix costs you one parameter per API call. The dynamic version costs you one function. Neither requires infrastructure changes.

@salimassili/ai-costguard implements this as maxOutputTokens enforcement in the session guard — the ceiling is calculated from remaining budget before each call and set automatically. The underlying pattern is always the same: compute the maximum output tokens your remaining budget can afford, set it explicitly, let the provider enforce it at the API level.

The bill for a ReasoningBomb call arrives before you can stop it.

The ceiling is the only defense positioned in the right place.


Repo: github.com/salimassili62-afk/ai-costguard

Top comments (0)