Every CVE Search/ Get API key

CVE-2026-57114

PraisonAI: Jobs webhook SSRF protection bypass via DNS rebinding

7.2 HighFix available

PraisonAI is a multi-agent teams system. From version 4.5.126 to before version 4.6.59, PraisonAI's Async Jobs API validates webhook_url when a job request is parsed and again when the internal Job object is constructed. That validation blocks direct loopback/private targets, but it is not bound to the later network request. When a job completes, _send_webhook() passes the original hostname to httpx.AsyncClient.post() with no send-time validation, IP pinning, or guarded transport. An attacker-controlled hostname can therefore resolve to a public IP during Pydantic validation and later resolve to loopback/private/cloud-metadata infrastructure during webhook delivery. This bypasses the intended SSRF guard in current supported releases. This appears to be an incomplete fix / patch bypass for GHSA-8frj-8q3m-xhgm. This issue has been patched in version 4.6.59.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
Low
Integrity
Low
Availability
None

Exploit likelihood

0.26%Unchanged since Oct 24, 2026
90%50%10%1%

What each source reports

CVE List Score used 7.2

PraisonAI: Jobs webhook SSRF protection bypass via DNS rebinding

PraisonAI is a multi-agent teams system. From version 4.5.126 to before version 4.6.59, PraisonAI's Async Jobs API validates webhook_url when a job request is parsed and again when the internal Job object is constructed. That validation blocks direct loopback/private targets, but it is not bound to the later network request. When a job completes, _send_webhook() passes the original hostname to httpx.AsyncClient.post() with no send-time validation, IP pinning, or guarded transport. An attacker-controlled hostname can therefore resolve to a public IP during Pydantic validation and later resolve to loopback/private/cloud-metadata infrastructure during webhook delivery. This bypasses the intended SSRF guard in current supported releases. This appears to be an incomplete fix / patch bypass for GHSA-8frj-8q3m-xhgm. This issue has been patched in version 4.6.59.

Record
CVE-2026-57114
CVSS 3.1
7.2 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N
Weakness
CWE-367, CWE-918
Updated
2026-11-02
EUVDEUVD-2026-108890 7.2

PraisonAI is a multi-agent teams system. From version 4.5.126 to before version 4.6.59, PraisonAI's Async Jobs API validates webhook_url when a job request is parsed and again when the internal Job object is constructed. That validation blocks direct loopback/private targets, but it is not bound to the later network request. When a job completes, _send_webhook() passes the original hostname to httpx.AsyncClient.post() with no send-time validation, IP pinning, or guarded transport. An attacker-controlled hostname can therefore resolve to a public IP during Pydantic validation and later resolve to loopback/private/cloud-metadata infrastructure during webhook delivery. This bypasses the intended SSRF guard in current supported releases. This appears to be an incomplete fix / patch bypass for GHSA-8frj-8q3m-xhgm. This issue has been patched in version 4.6.59.

Record
EUVD-2026-108890
CVSS 3.1
7.2 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-rjvw-7vvw-549v 7.2

PraisonAI: Jobs webhook SSRF protection bypass via DNS rebinding

Jobs webhook SSRF protection bypass via DNS rebinding

Summary

PraisonAI's Async Jobs API validates webhook_url when a job request is parsed and again when the internal Job object is constructed. That validation blocks direct loopback/private targets, but it is not bound to the later network request. When a job completes, _send_webhook() passes the original hostname to httpx.AsyncClient.post() with no send-time validation, IP pinning, or guarded transport.

An attacker-controlled hostname can therefore resolve to a public IP during Pydantic validation and later resolve to loopback/private/cloud-metadata infrastructure during webhook delivery. This bypasses the intended SSRF guard in current supported releases.

This appears to be an incomplete fix / patch bypass for GHSA-8frj-8q3m-xhgm ("Server-Side Request Forgery via Unvalidated webhook_url in Jobs API"). I defer to maintainers on whether this should be a new advisory/CVE or an amendment to the prior advisory, but current supported releases still appear affected.

Affected Component

Package:

praisonai

Files:

src/praisonai/praisonai/jobs/models.py
src/praisonai/praisonai/jobs/executor.py
src/praisonai/praisonai/jobs/router.py

Relevant code paths:

JobSubmitRequest.validate_webhook_url()
Job.validate_webhook_url()
JobExecutor._send_webhook()
POST /api/v1/runs

Affected Versions

Validated affected:

  • v4.5.126 (f00763937bf7f4d091e84533692fc0576fca9b99);
  • v4.5.128 (b4e3a8a8);
  • v4.6.56 (d3c4a2af);
  • v4.6.57 (e90d92231853161ad931f3498da57651a9f8b528);
  • current main (2f9677abb2ea68eab864ee8b6a828fd0141612e1, v4.6.57-4-g2f9677ab).

Suggested affected range for maintainer confirmation:

>= 4.5.126, <= 4.6.57

No patched version is known to me at submission time.

v4.5.124 and earlier are covered by the older unvalidated-webhook advisory. This report is scoped to patched-era releases where direct loopback/private webhook URLs are rejected but DNS rebinding still bypasses the guard.

Root Cause

Current validation is a time-of-check/time-of-use boundary:

  1. JobSubmitRequest.webhook_url is validated with urlparse() and socket.gethostbyname().
  2. The resolved address is rejected when it is private, loopback, link-local, or multicast.
  3. The original URL string is stored on the Job.
  4. After job completion, _send_webhook() creates a fresh httpx.AsyncClient and POSTs to the original URL.
  5. httpx resolves the hostname again. There is no revalidation of the address that is actually connected to.

The first DNS answer is therefore trusted for a later, independent DNS lookup. An attacker who controls DNS for the webhook hostname can return a public address during validation and an internal address during delivery.

Local Reproduction

The PoV is local-only. It starts a loopback HTTP server, monkeypatches resolver behavior in-process, and uses the real PraisonAI Job validator plus JobExecutor._send_webhook() sender.

Run from a PraisonAI checkout:

env PYTHONPATH=src/praisonai python3 poc_jobs_webhook_dns_rebinding_ssrf.py

Observed output on current main:

DIRECT_LOOPBACK_BLOCKED: {"Job": true, "JobSubmitRequest": true}
ACCEPTED_WEBHOOK_URL: http://rebind.test:<port>/hook
INTERNAL_SERVER_HIT: true
INTERNAL_REQUEST_HOST: rebind.test:<port>
INTERNAL_REQUEST_PATH: /hook
WEBHOOK_PAYLOAD_KEYS: completed_at,duration_seconds,error,job_id,result,status
WEBHOOK_PAYLOAD_STATUS: succeeded
PRAI-CAND-005 CONFIRMED: Jobs webhook validation is bypassed by DNS rebinding

The direct control proves that the current guard is meant to reject loopback webhook destinations. The rebind case proves the same blocked destination class is reached when the hostname changes between validation and delivery.

Full Local PoV Script

#!/usr/bin/env python3
"""Local PoV for PraisonAI Jobs webhook DNS-rebinding SSRF.

The PoV uses only loopback…
Record
GHSA-rjvw-7vvw-549v
CVSS 3.1
7.2 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N
Weakness
CWE-367, CWE-918
Updated
2026-11-02
NVD 7.2

PraisonAI is a multi-agent teams system. From version 4.5.126 to before version 4.6.59, PraisonAI's Async Jobs API validates webhook_url when a job request is parsed and again when the internal Job object is constructed. That validation blocks direct loopback/private targets, but it is not bound to the later network request. When a job completes, _send_webhook() passes the original hostname to httpx.AsyncClient.post() with no send-time validation, IP pinning, or guarded transport. An attacker-controlled hostname can therefore resolve to a public IP during Pydantic validation and later resolve to loopback/private/cloud-metadata infrastructure during webhook delivery. This bypasses the intended SSRF guard in current supported releases. This appears to be an incomplete fix / patch bypass for GHSA-8frj-8q3m-xhgm. This issue has been patched in version 4.6.59.

Record
CVE-2026-57114
CVSS 3.1
7.2 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N
Weakness
CWE-367, CWE-918
Updated
2026-11-02
OSV 7.2

PraisonAI: Jobs webhook SSRF protection bypass via DNS rebinding

PraisonAI is a multi-agent teams system. From version 4.5.126 to before version 4.6.59, PraisonAI's Async Jobs API validates webhook_url when a job request is parsed and again when the internal Job object is constructed. That validation blocks direct loopback/private targets, but it is not bound to the later network request. When a job completes, _send_webhook() passes the original hostname to httpx.AsyncClient.post() with no send-time validation, IP pinning, or guarded transport. An attacker-controlled hostname can therefore resolve to a public IP during Pydantic validation and later resolve to loopback/private/cloud-metadata infrastructure during webhook delivery. This bypasses the intended SSRF guard in current supported releases. This appears to be an incomplete fix / patch bypass for GHSA-8frj-8q3m-xhgm. This issue has been patched in version 4.6.59.

Record
CVE-2026-57114
CVSS 3.1
7.2 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N
Weakness
CWE-367, CWE-918
Updated
2026-11-02
OSVGHSA-rjvw-7vvw-549v 7.2

PraisonAI: Jobs webhook SSRF protection bypass via DNS rebinding

Jobs webhook SSRF protection bypass via DNS rebinding

Summary

PraisonAI's Async Jobs API validates webhook_url when a job request is parsed and again when the internal Job object is constructed. That validation blocks direct loopback/private targets, but it is not bound to the later network request. When a job completes, _send_webhook() passes the original hostname to httpx.AsyncClient.post() with no send-time validation, IP pinning, or guarded transport.

An attacker-controlled hostname can therefore resolve to a public IP during Pydantic validation and later resolve to loopback/private/cloud-metadata infrastructure during webhook delivery. This bypasses the intended SSRF guard in current supported releases.

This appears to be an incomplete fix / patch bypass for GHSA-8frj-8q3m-xhgm ("Server-Side Request Forgery via Unvalidated webhook_url in Jobs API"). I defer to maintainers on whether this should be a new advisory/CVE or an amendment to the prior advisory, but current supported releases still appear affected.

Affected Component

Package:

praisonai

Files:

src/praisonai/praisonai/jobs/models.py
src/praisonai/praisonai/jobs/executor.py
src/praisonai/praisonai/jobs/router.py

Relevant code paths:

JobSubmitRequest.validate_webhook_url()
Job.validate_webhook_url()
JobExecutor._send_webhook()
POST /api/v1/runs

Affected Versions

Validated affected:

  • v4.5.126 (f00763937bf7f4d091e84533692fc0576fca9b99);
  • v4.5.128 (b4e3a8a8);
  • v4.6.56 (d3c4a2af);
  • v4.6.57 (e90d92231853161ad931f3498da57651a9f8b528);
  • current main (2f9677abb2ea68eab864ee8b6a828fd0141612e1, v4.6.57-4-g2f9677ab).

Suggested affected range for maintainer confirmation:

>= 4.5.126, <= 4.6.57

No patched version is known to me at submission time.

v4.5.124 and earlier are covered by the older unvalidated-webhook advisory. This report is scoped to patched-era releases where direct loopback/private webhook URLs are rejected but DNS rebinding still bypasses the guard.

Root Cause

Current validation is a time-of-check/time-of-use boundary:

  1. JobSubmitRequest.webhook_url is validated with urlparse() and socket.gethostbyname().
  2. The resolved address is rejected when it is private, loopback, link-local, or multicast.
  3. The original URL string is stored on the Job.
  4. After job completion, _send_webhook() creates a fresh httpx.AsyncClient and POSTs to the original URL.
  5. httpx resolves the hostname again. There is no revalidation of the address that is actually connected to.

The first DNS answer is therefore trusted for a later, independent DNS lookup. An attacker who controls DNS for the webhook hostname can return a public address during validation and an internal address during delivery.

Local Reproduction

The PoV is local-only. It starts a loopback HTTP server, monkeypatches resolver behavior in-process, and uses the real PraisonAI Job validator plus JobExecutor._send_webhook() sender.

Run from a PraisonAI checkout:

env PYTHONPATH=src/praisonai python3 poc_jobs_webhook_dns_rebinding_ssrf.py

Observed output on current main:

DIRECT_LOOPBACK_BLOCKED: {"Job": true, "JobSubmitRequest": true}
ACCEPTED_WEBHOOK_URL: http://rebind.test:<port>/hook
INTERNAL_SERVER_HIT: true
INTERNAL_REQUEST_HOST: rebind.test:<port>
INTERNAL_REQUEST_PATH: /hook
WEBHOOK_PAYLOAD_KEYS: completed_at,duration_seconds,error,job_id,result,status
WEBHOOK_PAYLOAD_STATUS: succeeded
PRAI-CAND-005 CONFIRMED: Jobs webhook validation is bypassed by DNS rebinding

The direct control proves that the current guard is meant to reject loopback webhook destinations. The rebind case proves the same blocked destination class is reached when the hostname changes between validation and delivery.

Full Local PoV Script

#!/usr/bin/env python3
"""Local PoV for PraisonAI Jobs webhook DNS-rebinding SSRF.

The PoV uses only loopback…
Record
GHSA-rjvw-7vvw-549v
CVSS 3.1
7.2 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N
Weakness
CWE-367, CWE-918
Updated
2026-11-02
OSVPYSEC-2026-3519 7.2

PraisonAI: Jobs webhook SSRF protection bypass via DNS rebinding

Jobs webhook SSRF protection bypass via DNS rebinding

Summary

PraisonAI's Async Jobs API validates webhook_url when a job request is parsed and again when the internal Job object is constructed. That validation blocks direct loopback/private targets, but it is not bound to the later network request. When a job completes, _send_webhook() passes the original hostname to httpx.AsyncClient.post() with no send-time validation, IP pinning, or guarded transport.

An attacker-controlled hostname can therefore resolve to a public IP during Pydantic validation and later resolve to loopback/private/cloud-metadata infrastructure during webhook delivery. This bypasses the intended SSRF guard in current supported releases.

This appears to be an incomplete fix / patch bypass for GHSA-8frj-8q3m-xhgm ("Server-Side Request Forgery via Unvalidated webhook_url in Jobs API"). I defer to maintainers on whether this should be a new advisory/CVE or an amendment to the prior advisory, but current supported releases still appear affected.

Affected Component

Package:

praisonai

Files:

src/praisonai/praisonai/jobs/models.py
src/praisonai/praisonai/jobs/executor.py
src/praisonai/praisonai/jobs/router.py

Relevant code paths:

JobSubmitRequest.validate_webhook_url()
Job.validate_webhook_url()
JobExecutor._send_webhook()
POST /api/v1/runs

Affected Versions

Validated affected:

  • v4.5.126 (f00763937bf7f4d091e84533692fc0576fca9b99);
  • v4.5.128 (b4e3a8a8);
  • v4.6.56 (d3c4a2af);
  • v4.6.57 (e90d92231853161ad931f3498da57651a9f8b528);
  • current main (2f9677abb2ea68eab864ee8b6a828fd0141612e1, v4.6.57-4-g2f9677ab).

Suggested affected range for maintainer confirmation:

>= 4.5.126, <= 4.6.57

No patched version is known to me at submission time.

v4.5.124 and earlier are covered by the older unvalidated-webhook advisory. This report is scoped to patched-era releases where direct loopback/private webhook URLs are rejected but DNS rebinding still bypasses the guard.

Root Cause

Current validation is a time-of-check/time-of-use boundary:

  1. JobSubmitRequest.webhook_url is validated with urlparse() and socket.gethostbyname().
  2. The resolved address is rejected when it is private, loopback, link-local, or multicast.
  3. The original URL string is stored on the Job.
  4. After job completion, _send_webhook() creates a fresh httpx.AsyncClient and POSTs to the original URL.
  5. httpx resolves the hostname again. There is no revalidation of the address that is actually connected to.

The first DNS answer is therefore trusted for a later, independent DNS lookup. An attacker who controls DNS for the webhook hostname can return a public address during validation and an internal address during delivery.

Local Reproduction

The PoV is local-only. It starts a loopback HTTP server, monkeypatches resolver behavior in-process, and uses the real PraisonAI Job validator plus JobExecutor._send_webhook() sender.

Run from a PraisonAI checkout:

env PYTHONPATH=src/praisonai python3 poc_jobs_webhook_dns_rebinding_ssrf.py

Observed output on current main:

DIRECT_LOOPBACK_BLOCKED: {"Job": true, "JobSubmitRequest": true}
ACCEPTED_WEBHOOK_URL: http://rebind.test:<port>/hook
INTERNAL_SERVER_HIT: true
INTERNAL_REQUEST_HOST: rebind.test:<port>
INTERNAL_REQUEST_PATH: /hook
WEBHOOK_PAYLOAD_KEYS: completed_at,duration_seconds,error,job_id,result,status
WEBHOOK_PAYLOAD_STATUS: succeeded
PRAI-CAND-005 CONFIRMED: Jobs webhook validation is bypassed by DNS rebinding

The direct control proves that the current guard is meant to reject loopback webhook destinations. The rebind case proves the same blocked destination class is reached when the hostname changes between validation and delivery.

Full Local PoV Script

#!/usr/bin/env python3
"""Local PoV for PraisonAI Jobs webhook DNS-rebinding SSRF.

The PoV uses only loopback…
Record
PYSEC-2026-3519
CVSS 3.1
7.2 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
praisonai
PyPI
4.5.126 to 4.6.58
4.6.59
praisonai
PyPI
4.5.126 up to 4.6.59, plus listed versions
4.5.1274.5.1284.5.1294.5.1304.5.131
Show 45 moreShow less
4.5.1324.5.1334.5.1344.5.1354.5.1364.5.1374.5.1394.5.1404.5.1434.5.1444.5.1454.5.1494.6.104.6.114.6.124.6.134.6.144.6.154.6.164.6.184.6.194.6.204.6.214.6.224.6.234.6.244.6.254.6.264.6.274.6.284.6.294.6.304.6.314.6.324.6.334.6.344.6.354.6.364.6.374.6.384.6.394.6.404.6.414.6.424.6.43
4.6.59

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-57114 is a high vulnerability (CVSS 7.2) in Mervinpraison Praisonai, published June 18, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.26%, the 18th percentile. Fixed in praisonai 4.6.59.

References

This page doesn't list everything

Left out here: 15 versions and the rest of 3 source descriptions. The JSON record has them.

MoveEnter Open