AgenticMail: Unauthenticated inbound mail triggers bypassPermissions resume of the operator's Claude Code session (bridge-wake)
Date: 2026-06
Affected: npm/@agenticmail/openclaw, npm/@agenticmail/codex, npm/@agenticmail/claudecode
Attack vector: prompt-injection
Category: vulnerability-disclosure
Severity: High
CWE: CWE-306

## Summary Two inbound-mail handlers act on a privileged effect without verifying that the sender is the operator, while a sibling handler in the same repo does. The higher-impact one: any external email routed to the bridge inbox causes the dispatcher to resume the operator's Claude Code session with `permissionMode: 'bypassPermissions'`, embedding the attacker-controlled `from`/`subject`/`preview` verbatim into the prompt the resumed agent reads — an indirect prompt injection into a fully-privileged agent (Bash/Write/Edit/WebFetch + the agenticmail MCP toolbelt) running as the operator's OAuth identity. The sibling operator-query email-reply hook gates the same untrusted-From provenance with `isOperatorReplySender(replyFrom, config.operatorEmail)` (fail-closed); the bridge-wake path — a strictly higher-privilege effect — has no equivalent. ## Affected code (current HEAD, commit b95f52e) Untrusted provenance: external inbound email enters at `packages/api/src/routes/inbound.ts:41` (POST /mail/inbound); the `x-inbound-secret` authenticates only the relay->API hop, not the external sender, so `from`/`subject`/`preview` are attacker-controlled. Privileged sink (bridge-wake, bypassPermissions): - `packages/claudecode/src/dispatcher.ts:2040` `handleBridgeMail` extracts `subject`/`from`/`preview` (`:2045-2049`) and calls `planBridgeWake({ session, mail: { ..., from, preview } })` (`:2052`) with NO sender check — routing keys only on session freshness (skip-live / escalate / resu


Mitigations:

Architectural layers (MAESTRO):