Skip to content

bug(security/channels): channel_send can dispatch to a different recipient on the same channel (cross-chat message leak) #6117

Description

@houko

Summary

An agent's channel_send tool can dispatch a message to a different recipient than the current turn's inbound peer on the same channel, with no validation — a cross-chat message leak.

Observed live (2026-05-19): a claude-code driver agent received a WhatsApp message from its owner and dispatched two audio voice notes to a stranger's WhatsApp chat (a JID from a prior turn's context). Both messages landed in the wrong chat. Likely trigger: model hallucination / sticky context emitting channel_send with the wrong recipient.

Root cause

When a driver spawns a CLI subprocess and re-exposes LibreFang's tool surface through the /mcp HTTP bridge, the bridge has no notion of the current turn's peer: network.rs::mcp_http called execute_tool with sender_id: None and channel: None hardcoded.
So tool_channel_send has no peer scope to validate against, and a mis-targeted recipient on the same channel is dispatched unchecked.

Impact

Security / privacy: an agent can be induced (by hallucination or prompt manipulation) to send content intended for one contact to a different contact on the same channel. This is a confidentiality leak, not just a UX bug.

Repro (shape)

  1. Agent on a WhatsApp channel via the claude-code driver (CLI subprocess + /mcp bridge).
  2. Owner sends an inbound message; in the same or a later turn the model emits channel_send with a recipient JID belonging to a different chat.
  3. The message is delivered to the wrong recipient — no guard rejects the cross-chat dispatch.

Prior fix attempt

PR #5282 implemented an end-to-end fix: propagate the turn's peer scope (sender_user_id / sender_channel) through CompletionRequest → the claude-code driver's per-invocation mcp_config.json headers → /mcpexecute_tool, and add a guard in tool_channel_send that refuses a same-channel dispatch to a mismatched recipient (cross-channel dispatch stays allowed; legitimate cross-chat escalation routes through notify_owner).
That PR was closed unmerged during a stale-PR sweep, so the leak is most likely still present on main.
Re-verify the current behaviour before re-implementing, and confirm whether other drivers that bridge through /mcp share the missing-peer-scope gap.

Suggested labels

bug, area/security, area/channels, area/runtime

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/channelsMessaging channel adaptersarea/runtimeAgent loop, LLM drivers, WASM sandboxarea/securitySecurity systems and auditingbugSomething isn't workinghas-prA pull request has been linked to this issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions