# PraisonAI: Webhook SSRF via DNS fail-open in `JobSubmitRequest.validate_webhook_url()` — bypass of CVE-2026-40114

PraisonAI webhook validator fails open on DNS errors and re-resolves at send time, letting attackers DNS-rebind webhooks to internal IPs for SSRF.

- Payout: Research
- Severity: high
- Program: PraisonAI
- Found by: evertrustai
- Disclosed: 2026-08-25
- CVE: CVE-2026-55537
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-rg5q-pp8p-f7jm
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-rg5q-pp8p-f7jm
- Tags: area:ai domain:ai domain:web impact:internal-access kind:research platform:ghsa sev:high tech:python technique:incomplete-fix technique:race-window technique:source-review vuln:race-condition vuln:ssrf

**Target:** Jobs API webhook_url parameter / httpx webhook delivery
**Root cause:** validate_webhook_url() swallows socket.gaierror with `pass`, accepting unresolvable hostnames; _send_webhook() then performs a fresh independent DNS lookup via httpx at execution time, so the validated IP differs from the connected IP.
**Steps:**
1. Submit `POST /jobs` with `webhook_url` set to an attacker domain currently returning NXDOMAIN (e.g. `http://rebind.attacker.com/callback`); validator hits `except socket.gaierror: pass` and accepts it.
2. After submission, add DNS record `rebind.attacker.com A 127.0.0.1` with short TTL.
3. Wait for job completion; `_send_webhook()` calls `httpx.AsyncClient().post(job.webhook_url)` which resolves fresh to 127.0.0.1.
4. Internal service receives `POST /callback` with JSON job payload.
**How found:** Code review of the patch that added validate_webhook_url() for CVE-2026-40114: noticed the `except socket.gaierror: pass` fail-open and that _send_webhook() uses httpx with no cached resolution, giving a TOCTOU window between validation and delivery.
**Exploitation:** Attacker needs only the ability to submit jobs with a webhook_url and control of a domain's DNS. Validation-time NXDOMAIN bypasses the private-IP check; DNS is flipped to a private/loopback address before the queued job finishes, and the delayed webhook POST is delivered to the internal target carrying job result JSON. Internal services that act on POST bodies (Jenkins, Consul) can yield code execution; job results may leak credentials/agent data.
**Escalation:** Chaining the SSRF POST body into internal services that interpret JSON as commands (Jenkins webhook, Consul KV) to reach code execution; also exfiltration of job results to attacker endpoint.
**Insight:** When auditing SSRF fixes, check both the error path (does a failed DNS lookup fail open?) and whether the HTTP client re-resolves at request time — a validator that resolves once is useless if the sink resolves again later; also note transient resolver outages as a no-timing-attack bypass.

