# PraisonAI: AgentMail webhook mode accepts forged unsigned message.received events and invokes agents

PraisonAI's AgentMail webhook endpoint accepts unsigned or invalid-Svix message.received JSON and dispatches forged messages into the agent session, enabling unauthenticated remote agent invocation.

- Payout: Research
- Severity: high
- Program: PraisonAI
- Found by (vendor credit): rexpository
- Found by: rexpository
- Disclosed: 2026-10-07
- CVE: CVE-2026-61436
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-7c92-x8vg-4258
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-7c92-x8vg-4258
- Tags: area:ai domain:ai domain:web impact:integrity impact:internal-access kind:research platform:ghsa sev:high tech:python technique:source-review vuln:access-control vuln:auth-bypass

**Target:** aiohttp webhook endpoint in praisonai.bots.agentmail
**Root cause:** _handle_email_webhook() parses the JSON body and dispatches on the caller-controlled `type` field without reading the raw body or verifying Svix signature headers; the webhook secret returned by client.webhooks.create() is never stored or used.
**Steps:**
1. Start AgentMailBot with BotConfig(mode="webhook", webhook_path="/webhook"); endpoint binds 0.0.0.0.
2. POST JSON `{"type":"message.received","data":{"message_id":"msg-forged","from":"attacker@example.test","subject":"x","extracted_text":"forged body"}}` to the webhook path, optionally with bogus headers `svix-id: msg_bad`, `svix-timestamp: 1`, `svix-signature: v1,definitely-invalid`.
3. Handler returns 200 and schedules _process_webhook_payload(body) without any signature check.
4. BotMessage is built from attacker fields and _handle_message() calls self._session.chat(agent, sender_id, body) and replies to the attacker-controlled sender.
**How found:** Reporter compared AgentMail's documented Svix verification flow (svix-id/timestamp/signature over raw body) against PraisonAI's handler, noticed _handle_email_webhook() only calls request.json() and reads `type`, and that the secret from client.webhooks.create() is discarded; confirmed with a fake-request PoV including invalid-JSON, non-message, and duplicate controls.
**Exploitation:** Any network caller reaching the webhook URL posts a forged message.received body; the agent is invoked as an arbitrary sender, consuming model/API budget, injecting forged workflow input, and sending replies under the AgentMail inbox identity.
**Escalation:** Impact scales with the deployed agent's tools and context: unauthorized model calls, forged workflow input, and confidentiality/integrity loss when the agent has sensitive tool access.
**Insight:** When a provider SDK returns a webhook signing secret at registration time, check whether the integration actually persists and uses it; a handler that branches on a body field before touching raw bytes or headers is a signature-verification gap even if the SDK offers a verifier.

