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)
- Agent on a WhatsApp channel via the
claude-code driver (CLI subprocess + /mcp bridge).
- 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.
- 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 → /mcp → execute_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
Summary
An agent's
channel_sendtool 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-codedriver 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 emittingchannel_sendwith the wrongrecipient.Root cause
When a driver spawns a CLI subprocess and re-exposes LibreFang's tool surface through the
/mcpHTTP bridge, the bridge has no notion of the current turn's peer:network.rs::mcp_httpcalledexecute_toolwithsender_id: Noneandchannel: Nonehardcoded.So
tool_channel_sendhas no peer scope to validate against, and a mis-targetedrecipienton 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)
claude-codedriver (CLI subprocess +/mcpbridge).channel_sendwith arecipientJID belonging to a different chat.Prior fix attempt
PR #5282 implemented an end-to-end fix: propagate the turn's peer scope (
sender_user_id/sender_channel) throughCompletionRequest→ theclaude-codedriver's per-invocationmcp_config.jsonheaders →/mcp→execute_tool, and add a guard intool_channel_sendthat refuses a same-channel dispatch to a mismatchedrecipient(cross-channel dispatch stays allowed; legitimate cross-chat escalation routes throughnotify_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
/mcpshare the missing-peer-scope gap.Suggested labels
bug, area/security, area/channels, area/runtime