Skip to content

fix(query): run provider tool calls through hooks#37

Open
BunsDev wants to merge 1 commit into
mainfrom
codex/fix-tool-call-security-vulnerability
Open

fix(query): run provider tool calls through hooks#37
BunsDev wants to merge 1 commit into
mainfrom
codex/fix-tool-call-security-vulnerability

Conversation

@BunsDev
Copy link
Copy Markdown
Member

@BunsDev BunsDev commented Jun 3, 2026

Motivation

Non-Anthropic provider responses containing reconstructed ToolUse blocks were being executed directly, bypassing PreToolUse/plugin policy checks and PostToolUse hooks. This created a security bypass for attacker-controlled model output.

Description

  • When provider streams contain ToolUse blocks, execution is now routed through a shared, hook-aware executor instead of calling execute_tool directly.
  • Added execute_tool_blocks_with_hooks (and a small PreparedTool helper), which runs PreToolUse hooks and plugin pre-hooks, executes non-blocked tools concurrently, runs PostToolUse hooks and plugin post-hooks, and emits ToolStart/ToolEnd events.
  • Replaced the direct-execution path in the non-Anthropic provider dispatch with calls to the new helper, so the provider and Anthropic paths share the same policy enforcement and event semantics.

Testing

  • cargo check --package claurst-query — succeeded.
  • cargo test --package claurst-query — succeeded (unit tests for the claurst-query crate passed).
  • cargo check --workspace — failed due to a missing system dependency (alsa.pc / ALSA pkg-config) unrelated to this change.
  • cargo fmt --all -- --check and cargo clippy --package claurst-query --all-targets -- -D warnings did not pass cleanly due to pre-existing workspace formatting and clippy warnings outside this patch.

Copilot AI review requested due to automatic review settings June 3, 2026 12:11
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR closes a security gap in claurst-query where non-Anthropic provider responses that included reconstructed ToolUse blocks could trigger tool execution without going through PreToolUse policy checks (core hooks + plugin hooks) and PostToolUse hooks/events. It centralizes tool execution into a shared, hook-aware executor so Anthropic and non-Anthropic provider paths enforce the same policy and emit consistent ToolStart/ToolEnd events.

Changes:

  • Routes non-Anthropic provider ToolUse block execution through a shared hook-aware executor instead of calling execute_tool directly.
  • Replaces the inline streaming tool executor logic with a reusable execute_tool_blocks_with_hooks helper (sequential pre-hooks, concurrent execution, sequential post-hooks + events).
  • Ensures both provider and Anthropic tool execution paths share consistent policy enforcement and event semantics.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1965 to +1971
/// Execute tool invocations through the common policy-aware tool path.
async fn execute_tool_blocks_with_hooks(
tool_blocks: Vec<(String, String, Value)>,
tools: &[Box<dyn Tool>],
tool_ctx: &ToolContext,
event_tx: Option<&mpsc::UnboundedSender<QueryEvent>>,
) -> Vec<ContentBlock> {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants