Server Implementation
A tool handler allocates unbounded memory, time, or concurrency based on a parameter the caller controls, so a single call can hang or OOM the server. Generic compute/memory variant of the unbounded-cost family; paid-LLM cost is MCP-084, MCP sampling is MCP-211, oversized tool descriptions are MCP-252.
Resource exhaustion covers the CPU, memory, disk, and connection-pool versions of the same bug: the handler trusts an input to stay small. Classic shapes are `range(n)` with attacker-controlled `n`, regular-expression backtracking on untrusted input (ReDoS), image decoding without a pixel-count cap, and recursion on user-supplied data structures.
MCP servers are long-lived processes shared across the user's entire session. Crashing them is not a restart-and-recover inconvenience — it takes the whole agent workflow with it. A model that enters a loop of "try a bigger batch size," driven by a buggy tool description, can exhaust the host without any malice at all.
server.tool("expand_range", { n: z.number() }, async ({ n }) => { |
const items = Array.from({ length: n }, (_, i) => i); |
return { content: [{ type: "text", text: JSON.stringify(items) }] }; |
}); |
const MAX_ITEMS = 1_000; |
server.tool("expand_range", { n: z.number().int().positive().max(MAX_ITEMS) }, async ({ n }) => { |
const items = Array.from({ length: n }, (_, i) => i); |
return { content: [{ type: "text", text: JSON.stringify(items) }] }; |
}); |
We look for unbounded loops, allocations, and regular-expression evaluation driven by handler parameters. Schemas without `max` / `maxLength` / `maxItems` are surfaced for inputs that flow into allocators.
See the full threat catalog for every documented detection.
CVEs of the same CWE class. Not MCP-specific, but exemplify the failure mode MCPSafe detects.
MCPSafe runs this check — and every other rule in the catalog — on any MCP server you paste in.
Scan now