# AgenticMail: Unauthenticated inbound mail triggers bypassPermissions resume of the operator's Claude Code session (bridge-wake)

Unauthenticated inbound email to AgenticMail's bridge inbox resumes the operator's Claude Code session with bypassPermissions, injecting attacker-controlled from/subject/preview into a fully-privileged agent.

- Payout: Research
- Severity: high
- Program: AgenticMail
- Found by: matte1782
- Disclosed: 2026-06-18
- CVE: CVE-2026-57495
- Write-up quality: 8/10
- Original: https://github.com/advisories/GHSA-fq4x-789w-jg5h
- Library page: http://bugbountylibrary.com/r/ghsa%3AGHSA-fq4x-789w-jg5h
- Tags: area:ai domain:ai impact:integrity impact:rce kind:research platform:ghsa sev:high tech:llm tech:nodejs technique:source-review vuln:auth-bypass vuln:prompt-injection vuln:rce

**Target:** Inbound mail handler / bridge-wake dispatcher (npm @agenticmail/core, claudecode, codex, openclaw)
**Root cause:** handleBridgeMail routes external inbound mail to planBridgeWake/resumeBridgeSession with permissionMode 'bypassPermissions' without verifying the sender is the operator, unlike the sibling operator-query path that gates on isOperatorReplySender.
**Steps:**
1. External mail enters POST /mail/inbound (inbound.ts:41); x-inbound-secret only authenticates relay->API hop, so from/subject/preview are attacker-controlled.
2. dispatcher.ts:2040 handleBridgeMail extracts subject/from/preview (:2045-2049) and calls planBridgeWake (:2052) with no sender check.
3. planBridgeWake -> host-bridge.ts:141 composeBridgeWakePrompt embeds from/subject/preview (preview sliced to 600 chars) verbatim into the prompt.
4. bridge-wake.ts:103 resumeBridgeSession runs the prompt via Claude Code SDK with `permissionMode: 'bypassPermissions'` against the operator's last session (resume + same mcpServers).
5. Send mail from a non-operator address into the bridge inbox with subject/preview containing an instruction writing a CSPRNG marker; observe the resumed session act on it.
**How found:** Code review comparing sibling handlers: noticed the operator-query email-reply hook gates untrusted From with isOperatorReplySender (fail-closed) and the Telegram sibling gates on operatorChatId, while the higher-privilege bridge-wake path has no equivalent check.
**Exploitation:** Attacker sends email from any external address into the bridge inbox (relay sub-addressing or Cloudflare webhook). With a fresh <24h host-session saved, the dispatcher resumes the operator's Claude Code session under bypassPermissions, and the injected from/subject/preview text is read by the agent, which can then run arbitrary OS commands, read/write files, and exfiltrate under the operator's OAuth identity.
**Escalation:** Secondary instance: manager.ts:261 tryProcessApprovalReply releases a held outbound email on an 'approve' reply matched only by In-Reply-To/notification_message_id with no sender check.
**Insight:** When auditing agentic/LLM-integrated apps, diff every privileged sink that consumes untrusted message fields against sibling handlers in the same repo — the presence of a sender/auth gate on one path and its absence on a higher-privilege path is a reliable signal of CWE-306.

