v0.24.0 — Budget-cap security fixes
A whole-codebase audit (8 review angles, every finding adversarially re-verified) found that the v0.23.0 budget cap — the wallet-drain guardrail — had four independent bypasses. This release closes all of them plus a batch of correctness and robustness fixes.
Security / budget integrity
- Path traversal in passthrough tools —
rpc/surf/modal/phone/exa/search/defi/marketsonly stripped slashes, so a..segment (incl.%2e%2e/.%2e/ backslash encodings the URL parser normalizes) escaped the namespace and re-routed cheap calls onto expensive paid endpoints, defeating the per-tool budget pre-check and profile scoping. Newpath-safetyguards reject traversal/invalid chain slugs before any spend. - Concurrent-spend TOCTOU —
checkBudgetonly readspent; concurrent calls each passed a stale total and overran the cap. NewreserveBudget()atomically checks and reserves the estimate, released infinallyacross all 15 paid tools. routing:"smart"+routing_profile:"free"reserved$0but routed to a paid model — unmetered drain. Removed the$0special-case; corrected the misleading schema copy.
Correctness / robustness
- Manual-402 media tools no longer report a 5xx/429/425 outage as "fund your wallet";
formatErrorno longer reads$402.50as a status code;music/videoguard the probe-body parse. --profile constructor/__proto__falls back tofullinstead of crashing; a lagging RPC no longer yields$NaN USDC;fetchWithTimeoutcovers a stalled body; remote reference images are rejected byContent-Lengthbefore buffering; the key-leak scanner catches bare 64-hex keys.- JSON mode now honored on the native
anthropic/claude-*path;routing:"smart"+ multi-turnmessagesreturns a clear error instead of dropping history. - Dead
ServerContextremoved;realfaceenroll deduped ontopayAndPostJson.
64 unit tests (29 new). Full details in CHANGELOG.md.