CVE-2026-55535: PraisonAI: Server-Side Request Forgery via DNS rebinding bypass in webhook_url validation
Summary The webhookurl field in the Jobs API silently passes validation when DNS resolution fails (socket.gaierror), enabling DNS rebinding attacks. An attacker's domain can initially resolve to a public IP (passing validation) then switch to an internal IP before the server makes the HTTP request.
Details The validator catches socket.gaierror and silently allows the URL:
python src/praisonai/praisonai/jobs/models.py:55 try: ip = socket.gethostbyname(hostname) ipobj = ipaddress.ipaddress(ip) if ipobj.isprivate or ipobj.isloopback: raise ValueError("private address") except socket.gaierror: pass # BUG: DNS failure silently ignored → SSRF bypass
The HTTP call is made later with no re-validation:
python src/praisonai/praisonai/jobs/executor.py:402 async with httpx.AsyncClient() as client: await client.post(job.webhookurl, ...) # no second IP check
Proof of Concept
DNS rebinding flow: 1. Register attacker.com with TTL=1s → resolves to 1.2.3.4 (public IP) 2. Submit job: webhookurl=http://attacker.com/callback 3. Validation passes (public IP) 4. Switch DNS: attacker.com → 127.0.0.1 5. Job completes → server POSTs to 127.0.0.1 → internal SSRF
Unresolvable domain bypass (no DNS rebinding required):
bash curl -X POST http://:8005/api/v1/runs \ -d '{"prompt":"run","webhookurl":"http://unresolvable.internal/cb","agentyaml":"..."}' Validation: gaierror → pass → URL accepted
Impact SSRF to internal HTTP services: admin panels, databases, and cloud metadata APIs (e.g., http://169.254.169.254/). Exploitable without authentication.
Other sources
PraisonAI is a multi-agent teams system. Prior to praisonai 4.6.58, the Jobs API validatewebhookurl() path fails open on socket.gaierror and does not bind the validated address to the later request. An attacker webhookurl can later resolve to 127.0.0.1, 169.254.169.254, or another internal address. This issue is fixed in version 4.6.58.
— MITRE
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
pip/PraisonAIto a version that resolves this vulnerability.Fixed in 4.6.58 - Upgrade
Upgrade
praisonaito a version that resolves this vulnerability.Fixed in 4.6.58
Event History
Frequently Asked Questions
Who can exploit this issue?
An attacker does not need privileges or user interaction, but must be able to submit a job with a chosen webhook_url. They also need control of a DNS name so its resolution can change between URL validation and webhook delivery.
What can the vulnerable server be induced to contact?
A controlled hostname can pass validation while resolving to a public address, then be rebound to an internal, private, or loopback address before the job's HTTP POST occurs. The resulting request is made by the server through its HTTP client.
How can I check whether my deployment has the vulnerable behavior?
Inspect src/praisonai/praisonai/jobs/models.py for webhook URL validation that catches socket.gaierror and allows processing to continue. Also check src/praisonai/praisonai/jobs/executor.py for webhook delivery through httpx.AsyncClient().post without resolving and validating the destination again immediately before the request.