DEV Community

OnaEiuspkz
OnaEiuspkz

Posted on

IntentKit validated tool calls against the wrong list

IntentKit validated tool calls against the wrong list

Filtering the tools a model can see is a common way to limit what an agent may do. CVE-2026-76066 shows the limit of that approach when two components disagree about which list is authoritative: the model was shown a narrowed set, and the executor checked against the full registry instead.

The affected product

IntentKit is an agent platform that connects a language model to tooling, memory and social channels. The CVE record covers versions through 2.6.3, with the fix landing in commit 5b91da5.
The rated severity is 8.7 under CVSS 4.0, vector CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N. No privileges are required, no user interaction is required, and the impact is scored on integrity alone. That profile fits: the flaw does not leak data directly, it lets an unauthorised party cause state changes that should have required the owner.

Two lists, one decision

IntentKit uses ToolBindingMiddleware to narrow which tools are advertised to the model for a given request. The advertised set is a control surface. If the model cannot see a tool, it cannot sensibly select it, and a user reading the available actions sees a smaller blast radius.
The executor did something different. It validated incoming tool calls against the full tool registry rather than the per-request narrowed advertisement. A caller that supplies the exact name and arguments of a tool that was never advertised is therefore accepted.
The restricted tools named in the advisory are the owner-level ones: wallet transfer, posting, writing to memory, and call-agent. These are the actions a narrow advertisement design exists to keep out of reach of public callers.

How a caller reaches a de-advertised tool

Two paths appear in the record: indirect prompt injection, and replaying checkpoint or history data on a reused thread.
Both exploit the same gap between what the model was told and what the executor was willing to accept. In the injection path, content the agent processes carries an instruction to call a specific tool with specific arguments. The model does not need to have been offered the tool; the instruction can name it directly, and the executor will honour the name.
The replay path is subtler. A conversation thread may be resumed, with stored checkpoint or history data restored into context. Tool invocations persisted in that history can be re-presented in a context where the caller is not the owner. Because validation consults the registry rather than the current binding, the action executes with owner authority attached.
The record notes that this applies across the channel contexts: WEB, API, TWITTER and TELEGRAM. The last two matter for reachability, because they remove the need to touch the HTTP API at all. Anyone who can post to the agent's social surface is a candidate caller.

Why "the model cannot see it" is not an authorization control

Capability filtering and authorization are different mechanisms that are easy to conflate. Filtering reduces the probability that a well-behaved model selects a dangerous action. Authorization decides whether the action is permitted when it is requested, regardless of who requested it and regardless of whether it was advertised.
A design that relies only on filtering fails in three familiar ways. The set of names is discoverable through prompts, documentation or error messages. The model is not the only party that can construct a tool call. And history, checkpoints and replays carry old calls into new contexts with different privilege assumptions.
The correct shape is a check at execution time, against the binding that applies to the current request and identity, with the full tool name compared to the narrowed set. If that comparison fails, the call is refused and the refusal is logged.

Response steps

  • Upgrade past 2.6.3 or apply the commit referenced in the record. Confirm the executor now validates against the per-request binding rather than the registry.
  • Enumerate the owner-only tools that each deployment enables. Wallet transfer and call-agent are the ones with the largest consequences; if they are not needed for the agent's purpose, remove them rather than relying on the fix.
  • Check for evidence of use. Look for tool invocations whose names do not appear in the advertised set for the corresponding request, and for agent actions at times when no owner was interacting.
  • Review thread reuse. Shared threads and resumed checkpoints carry prior context; if a thread can be resumed by a different caller, the boundary is weak regardless of tool filtering.
  • Treat social channels as interfaces. A Twitter or Telegram integration that accepts commands from non-owners needs its own authorization model, because it bypasses the web session that administrators assume is the front door.

Where this fits

Agent frameworks are converging on the same architecture: a tool registry, a per-request binding layer, and an executor. The security property depends on the executor trusting the binding layer rather than the registry. When the validation step reads the broader of the two, the narrower one stops being a control and becomes documentation.

References

Top comments (0)