{"id":"CVE-2026-55535","aliases":["GHSA-hmfx-4v44-9qw9","PYSEC-2026-3890"],"title":"PraisonAI vulnerable to Server-Side Request Forgery via DNS rebinding bypass in webhook_url validation","summary":"PraisonAI vulnerable to Server-Side Request Forgery via DNS rebinding bypass in webhook_url validation","severity":"medium","cvss":6.8,"cvssVector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:N/A:N","vendor":"praisonai","product":"praisonai","ecosystem":"pip","affected":["praisonai < 4.6.58"],"patched":["praisonai 4.6.58"],"published":"2026-08-25","updated":"2026-09-10","sourceUpdated":"2026-09-10T12:26:06.189526398Z","source":"OSV","sourceUrl":"https://osv.dev/vulnerability/GHSA-hmfx-4v44-9qw9","references":[{"url":"https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-hmfx-4v44-9qw9"},{"url":"https://github.com/MervinPraison/PraisonAI/commit/2f9677abb2ea68eab864ee8b6a828fd0141612e1"},{"url":"https://github.com/MervinPraison/PraisonAI"},{"url":"https://github.com/MervinPraison/PraisonAI/releases/tag/v4.6.58"},{"url":"https://pypi.org/project/praisonai"},{"url":"https://github.com/advisories/GHSA-hmfx-4v44-9qw9"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-55535"}],"tags":["osv","pip","nvd","ghsa"],"epss":0.00219,"epssPercentile":0.12653,"cwe":["CWE-367","CWE-918"],"ingestedAt":"2026-08-25T15:27:53.303Z","slug":"CVE-2026-55535","body":"## Overview\n\n### Summary\nThe `webhook_url` 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.\n\n### Details\nThe validator catches `socket.gaierror` and silently allows the URL:\n\n```python\n# src/praisonai/praisonai/jobs/models.py:55\ntry:\n    ip = socket.gethostbyname(hostname)\n    ip_obj = ipaddress.ip_address(ip)\n    if ip_obj.is_private or ip_obj.is_loopback:\n        raise ValueError(\"private address\")\nexcept socket.gaierror:\n    pass  # BUG: DNS failure silently ignored → SSRF bypass\n```\n\nThe HTTP call is made later with no re-validation:\n\n```python\n# src/praisonai/praisonai/jobs/executor.py:402\nasync with httpx.AsyncClient() as client:\n    await client.post(job.webhook_url, ...)  # no second IP check\n```\n\n### Proof of Concept\n\n**DNS rebinding flow:**\n1. Register `attacker.com` with TTL=1s → resolves to `1.2.3.4` (public IP)\n2. Submit job: `webhook_url=http://attacker.com/callback`\n3. Validation passes (public IP)\n4. Switch DNS: `attacker.com` → `127.0.0.1`\n5. Job completes → server POSTs to `127.0.0.1` → internal SSRF\n\n**Unresolvable domain bypass (no DNS rebinding required):**\n\n```bash\ncurl -X POST http://:8005/api/v1/runs \\\n  -d '{\"prompt\":\"run\",\"webhook_url\":\"http://unresolvable.internal/cb\",\"agent_yaml\":\"...\"}'\n# Validation: gaierror → pass → URL accepted\n```\n\n### Impact\nSSRF to internal HTTP services: admin panels, databases, and cloud metadata APIs (e.g., `http://169.254.169.254/`). Exploitable without authentication.\n\n## Affected packages\n\n- `praisonai < 4.6.58`\n\n## Remediation\n\nUpgrade to a patched release:\n\n- `praisonai 4.6.58`","depth":"sunlit","depthScore":37,"depthScoreParts":{"impact":37.4,"likelihood":0,"exploitation":0,"ransomware":0},"changes":[]}