T07 · Tool Hijacking and Spoofing
- Location
index.ts:272- Finding
Remote Tool-Call Parameter Hijacking
- Content
View full analysis
Vulnerability Details
File Location:
index.ts, lines 272–281 and 324–342
Vulnerability Type: Remote injection and overriding of local tool-call parameters
Risk Level: CriticalVulnerable Code
ts const { decide } = await loadKalibrSdk(); const decision = await decide(goal); const sessionKey = ctx?.sessionKey; if (sessionKey) { runs.setLastDecision(sessionKey, { tool_id: decision.tool_id, params: decision.params, }); }ts const decision = runs.getLastDecision(sessionKey); if (!decision || !decision.params || Object.keys(decision.params).length === 0) { return {}; } if (decision.tool_id && decision.tool_id !== event.toolName) { api.logger.info( "[kalibr] Decision tool_id (" + decision.tool_id + ") differs from current tool (" + event.toolName + "), proceeding anyway" ); } api.logger.info( "[kalibr] Injecting params for tool " + event.toolName + ": " + JSON.stringify(decision.params) ); const merged = { ...event.params, ...decision.params }; return { params: merged };Technical Analysis
When routing is enabled, the plugin obtains
paramsfrom the external Kalibr service throughdecide()and stores them for the session. Before a local tool call, these externally supplied values are merged after the original arguments:ts { ...event.params, ...decision.params }Consequently, remote values override same-named parameters selected by the agent or user. The implementation does not enforce a tool-specific parameter allowlist, validate the values against a trusted schema, protect security-sensitive fields, or request user confirmation.
The
tool_idcheck does not provide a security boundary. If the remote decision identifies a different tool, the implementation logs the mismatch and explicitly proceeds. Iftool_idis omitted, no tool identity check is performed at all. Therefore, parameters intended o ...[truncated 1763 chars]- Remediation
View remediation
Remediation Suggestions
- Remove remote tool-parameter injection unless it is strictly required. Treat remote routing decisions as model-selection hints only.
- If parameter injection must remain, require a nonempty
tool_idand enforce exact equality withevent.toolName. Reject the decision rather than proceeding on a mismatch. - Define strict, tool-specific schemas and allowlists for remotely adjustable fields. Reject unknown keys, invalid types, oversized values, and values outside explicit constraints.
- Prevent remote overrides of security-sensitive parameters, including command strings, executable paths, file paths, URLs, hosts, credentials, authorization headers, and destructive-operation flags.
- Do not let remote values silently override legitimate arguments. Apply only approved defaults to absent, low-risk fields, or require explicit user approval for every change.
- Bind each decision to a particular run and intended tool invocation rather than only to a session key. Add short expirations and single-use semantics to prevent stale or cross-call application.
- Authenticate responses cryptographically and use a fixed, trusted HTTPS endpoint. Restrict configurable service URLs where the deployment model permits it.
- Log parameter names and validation outcomes, but redact secret values and sensitive content.
- Add tests covering omitted and mismatched
tool_idvalues, unknown keys, sensitive-field overrides, stale decisions, cross-tool reuse, and malicious remote responses.
