system: OPERATIONAL
← back to all hacks
AGENTS CRITICAL

PraisonAI CVE-2026-44338: an unauthenticated agent server, exploited in 3h44

Disclosed May 11, 2026, CVE-2026-44338 ships PraisonAI with authentication hard-disabled in its legacy API server. A CVE-Detector scanner hit the endpoint less than four hours later.

2026-05-25 // 6 min affects: praisonai-2.5.6-to-4.6.33, flask-api-server, multi-agent-orchestration

What is this?

On May 11, 2026 at 13:56 UTC, GitHub published advisory GHSA-6rmh-7xcm-cpxj, assigned CVE-2026-44338 (CVSS 7.3, High), for PraisonAI — a popular open-source multi-agent orchestration framework with around 7,100 GitHub stars. The shipped legacy Flask API server, src/praisonai/api_server.py, hard-disables authentication by default. Any caller that can reach the process can list agents and trigger the configured workflow without presenting a token.

The Sysdig Threat Research Team observed the first targeted probe — a scanner identifying itself as CVE-Detector/1.0 — landing on a sensor at 17:40 UTC the same day, three hours and 44 minutes after the advisory went public. Versions 2.5.6 through 4.6.33 are vulnerable; the fix shipped in 4.6.34 on PyPI. The flaw was reported by GitHub user shmulc8.

How it works

The advisory describes three cooperating defects, all visible in the public source tree:

# src/praisonai/api_server.py — illustrative excerpt of the affected logic
AUTH_ENABLED = False        # hard-coded constant
AUTH_TOKEN   = None         # never read from env, never overridable at runtime

def check_auth():
    if not AUTH_ENABLED:
        return True         # both "protected" routes fail open
    # ...

The two endpoints behind that gate are unguarded in practice:

  • GET /agents returns the agents.yaml filename and the list of configured agents.
  • POST /chat accepts any JSON body containing a message key, ignores the value, and runs PraisonAI(agent_file="agents.yaml").run() — i.e. the operator’s full agent graph.

When the script is launched directly, it also binds to 0.0.0.0:8080. The companion APIConfig in src/praisonai/praisonai/deploy/models.py keeps auth_enabled = False as a default, and the generated sample deployment YAML recommends host: 0.0.0.0 alongside auth_enabled: false — silently propagating the insecure default into operator-owned deployments. The newer serve agents command path is unaffected: it binds to 127.0.0.1 and accepts --api-key.

Sysdig’s honeypot captured the recon pattern that followed disclosure. A single host on DigitalOcean (146.190.133.49) ran two scanner passes eight minutes apart, sweeping ~70 requests each. The second pass narrowed to AI-agent fingerprints (/praisonai/version.txt, /pyproject.toml, /docs, /openapi.json) and then sent the validation probe: GET /agents with no Authorization header and User-Agent: CVE-Detector/1.0. The host returned 200 OK with the agent list, confirming the bypass.

Why it matters

The bypass itself is not arbitrary code execution. The /chat handler ignores the submitted message, so the attacker cannot inject a free-form prompt. What they get is unauthenticated invocation of whatever the operator’s agents.yaml is wired to do — and in production deployments that usually includes a code_interpreter, shell or file I/O tool, web fetch, or an HTTP client. The realistic impact ceiling is therefore: model-quota draining at the cheap end, agent-tool execution and configuration disclosure at the expensive end.

Two broader points make this CVE worth studying:

  • The pattern is recurring across the AI-agent stack. Sysdig links it to recent rapid-exploitation cases on Marimo, LMDeploy (CVE-2026-33626) and Langflow (CVE-2026-33017) — all small-to-medium projects whose internet-facing default exposes a powerful runtime to anonymous callers.
  • Three-and-a-half hours is the new baseline. A ~7,100-star repo is no longer “below the radar”. Adversary tooling now reverses patches, generates scanners, and probes the public IPv4 space at advisory speed.

Defenses

  1. Upgrade immediately. Move to PraisonAI 4.6.34 or later. Anything in the 2.5.64.6.33 range is vulnerable as shipped.
  2. Stop using the legacy entrypoint. Switch to the serve agents command, which binds to 127.0.0.1 and requires --api-key. Treat api_server.py as deprecated.
  3. Audit deployment templates. If your infra-as-code was generated from PraisonAI’s sample, search it for auth_enabled: false and host: 0.0.0.0. Both should be inverted.
  4. Default-deny on agent triggers. Any HTTP path that ends in PraisonAI(...).run() — or its equivalent in LangChain/CrewAI/AutoGen wrappers — is a state-changing action and should require authentication, not opt into it.
  5. Detect at the perimeter. Successful unauthenticated calls leave no missing-auth signal in app logs. Add WAF rules for GET /agents and POST /chat lacking an Authorization header, and flag the User-Agent: CVE-Detector/1.0 string anywhere it appears.
  6. Audit model-provider billing and agents.yaml secrets for activity after May 11, 2026, and rotate any credentials referenced by the workflow.

Status

ItemReferenceDateNotes
GitHub advisoryGHSA-6rmh-7xcm-cpxj2026-05-11 13:56 UTCCVSS 7.3, CWE-306 / CWE-668 / CWE-1188
CVE IDCVE-2026-443382026-05-11NVD-published
First targeted probeSysdig TRT sensor2026-05-11 17:40 UTCCVE-Detector/1.0, ~3h44 after disclosure
Patched releasePraisonAI 4.6.342026-05-11PyPI
Vulnerable range2.5.6 — 4.6.33All prior versions also vulnerable for the legacy script

The deeper takeaway is structural. The PraisonAI legacy server is a small bug — three lines, one default, one bind address — but it sits at the same junction every multi-agent framework reaches sooner or later: an HTTP trigger that, behind the curtain, runs an arbitrary tool-using agent. Frameworks that ship that trigger with authentication opt-in instead of opt-out should be assumed exploitable on first internet exposure.

Sources