GHSA-hmfx-4v44-9qw9: SSRF
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.
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
Event History
Frequently Asked Questions
What does an attacker need to exploit this issue?
The attacker needs to submit a Jobs API webhook URL for a domain they control. They must make the domain resolve to a public IP during validation and then change its DNS record to an internal, private, or loopback IP before the job's webhook request is sent.
Which systems are at risk?
PraisonAI deployments that accept attacker-controlled webhook_url values through the Jobs API are exposed. The resulting request is sent from the PraisonAI server, so internal services reachable from that server may be targeted.
How can I determine whether my code contains the vulnerable behavior?
Check the Jobs API webhook URL validator for handling of socket.gaierror that allows validation to continue, and check whether the later httpx AsyncClient POST revalidates the resolved destination IP. The vulnerable flow permits DNS-resolution failures during validation and performs no second IP check before the request.