GHSA-x92v-rpx6-p6cwHigh· 8.6▾ TwilightPraisonAI: Webhook signature verification skipped (fail-open) when secret unset, allowing forged inbound webhooks (WhatsApp & Linear bots)
▾ Twilight zone — High severity, or a signal on a lesser flaw
impact 47.3 · likelihood 0 · exploitation 0
Need a working PoC? Pro members can cast a request and our team develops one — it lands right here.
The WhatsApp and Linear bot adapters verify the inbound webhook HMAC signature only when a secret is configured. When the secret environment variable is unset — the default on a fresh install and common in development — verification is skipped entirely and the webhook body is parsed and dispatched as a genuine, trusted event. A remote, unauthenticated attacker who can reach the bot's webhook endpoint can inject arbitrary platform events.
Affected code:
WhatsApp - src/praisonai/praisonai/bots/whatsapp.py
if self._app_secret: gates the ENTIRE check; when falsy the body is
json.loads()'d and dispatched to _process_webhook_data() with no verification.Linear - src/praisonai/praisonai/bots/linear.py
if self._signing_secret: fail-open guard.The _verify_signature implementations themselves are correct (constant-time HMAC-SHA256); the defect is that verification is bypassed when the secret is absent.
Impact:
Proof of concept (bot started without the secret - the default):
curl -X POST http://VICTIM:PORT/webhook
-H 'Content-Type: application/json'
-d '{"object":"whatsapp_business_account","entry":[{"changes":[{"value":
{"messages":[{"from":"15551234567","id":"wamid.x","type":"text",
"text":{"body":"attacker-injected message"}}]}}]}]}'
A self-contained PoC that executes the real _handle_webhook / _verify_signature source extracted from the repo confirms: secret unset -> status 200, payload dispatched (VULNERABLE); secret set + no signature -> status 403, nothing dispatched (control).
Remediation: Fail closed. When no secret is configured, reject all webhooks (HTTP 403) and refuse to start the adapter unless a secret is set (or an explicit, clearly-named insecure-dev override is given):
if not self._app_secret: return web.Response(status=403, text="Webhook secret not configured") signature = request.headers.get("X-Hub-Signature-256", "") if not self._verify_signature(body, signature): return web.Response(status=403, text="Invalid signature")
Distinct from prior advisories: The accepted default-insecure advisories cover a different surface/mechanism — CALL_SERVER_TOKEN unset (GHSA-86qc-r5v2-v6x6) and the JWT key default "dev-secret-change-me" (GHSA-3qg8-5g3r-79v5). This is in the bot webhook adapters and the mechanism is skipping signature verification entirely when the secret is absent, not a weak default key.
praisonai <= 4.6.52Upgrade to a patched release:
praisonai 4.6.59Connected by shared product, vendor, weakness, or advisory.
CVE-2026-57122High· 8.6PraisonAI is a multi-agent teams system
GHSA-8579-rgg5-ph2mHigh· 8.8PraisonAI DiscordApproval accepts unrelated channel messages as dangerous-tool approvals
GHSA-fc26-m9pf-v56qHigh· 8.6PraisonAI LinearBot processes unsigned webhooks when LINEAR_WEBHOOK_SECRET is missing
CVE-2026-55529Medium· 6.9PraisonAI has an origin validation bypass in MCP HTTP Stream transport that allows browser-mediated unauthenticated tool execution on loc…
CVE-2026-55531Medium· 6.5PraisonAI MCP HTTP server has unauthenticated unbounded session accumulation (memory exhaustion; session TTL never enforced)
CVE-2026-55534High· 8.6PraisonAI serve agents --api-key is ignored, allowing unauthenticated remote agent execution