Hoch

PraisonAI: Jobs API is unauthenticated by default and allows attacker-controlled webhook SSRF

  • Veröffentlicht: 08.10.2026
  • Aktualisiert: 15.10.2026 18:17

Summary

PraisonAI's Async Jobs API enables its API-key middleware only when PRAISONAI_JOBS_API_KEY is set, so by default every endpoint is unauthenticated. An unauthenticated POST /api/v1/runs accepts an attacker-controlled webhook_url; on job completion the server POSTs the job payload to it via httpx. The webhook_url has an SSRF validator (gethostbyname + private-IP check), but it validates at request time while httpx re-resolves at connection time — a DNS-rebinding TOCTOU that reaches internal services. Runtime-confirmed as an unauthenticated, blind SSRF (the internal canary received the POST; the internal response is not returned to the attacker). Severity Medium.

Details

Affected component

  • Package: praisonai 4.6.63. Files: src/praisonai/praisonai/jobs/server.py, jobs/router.py, jobs/executor.py, jobs/models.py.

Vulnerable code / root cause

Path: src/praisonai/praisonai/jobs/server.py

Function: create_app

Snippet:

python
jobs_api_key = os.environ.get("PRAISONAI_JOBS_API_KEY")
# ...
if jobs_api_key:
    app.add_middleware(JobsAPIKeyMiddleware)   # auth ONLY when env var is set

Issue: with the env var unset (default), no auth middleware is added → all endpoints unauthenticated. Default bind is 127.0.0.1.

Path: src/praisonai/praisonai/jobs/router.py

Function: submit_job

Snippet:

python
@router.post("", response_model=JobSubmitResponse, status_code=202)
async def submit_job(request, response, body: JobSubmitRequest, ...):
    # no auth dependency; body.webhook_url is attacker-controlled
    job = Job(prompt=body.prompt, webhook_url=body.webhook_url, ...)
    await executor.submit(job)

Issue: attacker-controlled webhook_url flows into the job with no authentication on the endpoint.

Path: src/praisonai/praisonai/jobs/models.py (validator) and src/praisonai/praisonai/jobs/executor.py (sink)

Function: validate_webhook_url → _send_webhook

Snippet:

python
# models.py validate_webhook_url (CHECK time)
ip = socket.gethostbyname(hostname)
if ipaddress.ip_address(ip).is_private or ...:
    raise ValueError("Webhook URL resolves to a private or restricted network address")

# executor.py _send_webhook (CONNECT time, re-resolves, no pinning)
async with httpx.AsyncClient(timeout=30.0) as client:
    response = await client.post(job.webhook_url, json=payload, ...)

Issue: the validator resolves the hostname at validation time but does not pin the IP for the httpx.post connection → DNS rebinding (independent resolution at check vs connect) bypasses it and reaches internal services.

Attack flow

  1. Operator runs the Jobs API without PRAISONAI_JOBS_API_KEY (default → unauth).
  2. Attacker POST /api/v1/runs with webhook_url = a rebinding domain.
  3. The validator(s) see a public IP (pass); on completion httpx.post re-resolves to an internal IP and connects → SSRF to internal.

Why existing protection is bypassed

Auth is opt-in (only when the env var is set). The webhook_url validator resolves at check time but does not pin the IP for the connection → DNS-rebinding TOCTOU. (Correction to an earlier static note: the guard exists but is bypassable.)

Security boundary

Unauthenticated network peer → server-side request to internal services (Scope: Changed). Default bind 127.0.0.1 limits remote reach unless the operator binds non-loopback.

Proof of Concept

Environment

Real Jobs API (python -m praisonai.jobs.server, no API key) in a local runtime (127.0.0.1:18085), resolver pointed at the controlled rebinding DNS, internal canary Docker-internal only. Runnable assets: PraisonAI-Runtime-Repro\runtime-files\ (docker-compose.jobs.yml).

Steps to reproduce

  1. PRAI-04-01-Jobs-Submit-NoAuth: POST /api/v1/runs {"prompt":"hello"} → 202 (no auth).
  2. PRAI-04-02-Jobs-Webhook-SSRF-Blind: POST /api/v1/runs {"prompt":"hello","webhook_url":"http://rebind.lab:8081/secret"} → 202.

Expected result

Unauthenticated job submission should be rejected; the webhook SSRF guard should prevent reaching internal services regardless of DNS timing.

Impact

Unauthenticated job submission (LLM cost abuse); SSRF to internal services (blind, DNS-rebinding); exfiltration of the job result to an attacker-controlled webhook.

Suggested remediation

  • Authenticate the Jobs API by default (auto-generate a token / fail closed when binding non-loopback), like the gateway.
  • For webhook_url: resolve once, reject private/loopback/CGNAT/metadata, then pin and connect to the validated IP; disable redirects.

Betroffene Software

Klicken Sie auf eine Technologie, um alle zugehörigen Schwachstellen anzuzeigen.

PlattformPaketAnfällige VersionenBehoben in
Python (PyPI) praisonai < 4.6.78 4.6.78

Verweise

CVSS-Wert 7.2/10
CVSS-Vektor
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N
Schwäche (CWE)
CWE-200, CWE-306, CWE-367, CWE-918
Plattform
Python (PyPI)
Paket
praisonai
Veröffentlicht
08.10.2026
Aktualisiert
15.10.2026 18:17

Quellen und Lizenzen

OSV / GitHub Advisory Database - PYSEC-2026-4249 - PyPA Advisory Database; CC BY 4.0

OSV / GitHub Advisory Database - GHSA-4w49-gwv8-fpjg - CC BY 4.0

Schwachstellenhistorie: praisonai

Alle veröffentlichten Schwachstellen dieses Pakets (Python (PyPI)), neueste zuerst. Zeigt, ob es ein einmaliger Ausrutscher ist oder ein Paket, das man im Auge behalten muss.

Alle (104) im Archiv
Einträge insgesamt
104
Erste → letzte
04.2026 10.2026
Ohne Fix
0
In Angriffen ausgenutzt
0

Verteilung nach Schweregrad

  • Kritisch 27
  • Hoch 60
  • Mittel 17

Veröffentlichungen pro Jahr

  1. 2026: 104
Schweregrad:
  1. PraisonAI: Jobs API is unauthenticated by default and allows attacker-controlled webhook SSRF dieser Eintrag
    Hoch · 7.2 CVE-2026-60091 < 4.6.78 4.6.78
  2. Hoch · 7.5 CVE-2026-61439 < 4.6.78 4.6.78
Mehr anzeigen (20) 20 von 87 angezeigt

Erkennen Sie Schwachstellen in Ihrer Anwendung

Mit der DockRay-Integration und aktivierter Softwareinventarisierung prüft DockRay gemeldete Komponentenversionen auf bekannte Schwachstellen und benachrichtigt Sie über bestätigte Treffer. Die Abdeckung hängt von der unterstützten Technologie und den verfügbaren Meldungen ab.

Anwendung verbinden
DockRay Newsletter

Anwendungssicherheit in Ihrem Postfach

Wichtige Schwachstellen, konkrete Empfehlungen und praktische Tipps für Ihre Anwendungen. Wählen Sie Ihre Technologien und verfolgen Sie, was für Ihr Projekt relevant ist.

  • Eine tägliche Zusammenfassung neuer Schwachstellen, auch kritischer.
  • Benachrichtigungen über wichtige Updates.
  • Praktische Tipps zur Sicherheit und Überwachung von Anwendungen.

Leer lassen, um Meldungen zu allen Technologien zu erhalten.

Kostenlos anmelden. In jeder E-Mail mit einem Klick abmelden.