Executive brief
PraisonAI's job submission API allows users to specify a webhook URL that receives job completion results. The validation code for this URL fails silently when DNS lookup errors occur, and the actual webhook POST happens later with a fresh DNS lookup. This allows an attacker to submit a job with a hostname that doesn't currently resolve (bypassing validation), then update their DNS records to point to internal infrastructure (e.g., 127.0.0.1) before the job completes, causing the server to send sensitive job data to internal systems or enabling further exploitation.
Technical details
The vulnerability consists of two flaws in praisonai/jobs/models.py and praisonai/jobs/executor.py. First, the validate_webhook_url() method catches socket.gaierror exceptions and silently passes (line 63), allowing URLs with unresolvable hostnames to be accepted. Second, the _send_webhook() method in executor.py performs an independent DNS lookup at execution time via httpx.AsyncClient().post(), creating a TOCTOU window. An attacker can exploit this by: (1) submitting a job with webhook_url pointing to an attacker-controlled domain currently returning NXDOMAIN, passing validation; (2) updating DNS to resolve that domain to 127.0.0.1 or another private IP; (3) when the job completes minutes/hours later, _send_webhook() resolves the hostname fresh and POSTs to the internal IP. The attack requires network-level access to the Jobs API and control over DNS for a domain. Alternatively, if DNS resolution fails transiently (rate limiting, temporary outage), a webhook is accepted unconditionally, allowing bypass of private IP checks. Patched in version 4.6.58.
Affected products
- MervinPraison PraisonAI < 4.6.58
Timeline
- 2026-06-13: disclosed
- 2026-06-13: patched: Fixed in version 4.6.58
- 2026-08-25: advisory