Skip to main content

PraisonAI EUVDEUVD-2026-65514

| CVE-2026-55538 HIGH
Missing Authentication for Critical Function (CWE-306)
2026-08-25 https://github.com/MervinPraison/PraisonAI GHSA-r7v3-x45f-g7hp
7.3
CVSS 3.1 · Vendor: https://github.com/MervinPraison/PraisonAI
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Identify network-exposed PraisonAI serve port
  2. Delivery
    Send unauthenticated POST /agents/{name} with arbitrary query payload
  3. Exploit
    _create_agents_app() routes request with no auth checks
  4. Execution
    agent.start() executes attacker-controlled query
  5. Impact
    Receive full agent response including downstream tool outputs

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A07:2025 - Authentication Failures
ASVS 5.0
V6 - Authentication Authentication required for critical functions
MITRE ATT&CK

1 technique across 1 tactic: Initial Access

The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up.

Exploitation Conditions

The vulnerable service must be running pip/praisonai at a version earlier than 4.6.58 via the praisonai serve agents command. The service must be bound to a network-reachable interface - the default localhost binding limits exposure to local access only, but --host 0.0.0.0 (common for workflow tool integrations) exposes it to the broader network. No authentication credentials, no API key, no session token, and no special headers of any kind are required; any HTTP client reaching the port can trigger the vulnerability. For the /agents/{agent_name} route the attacker must know or enumerate a valid registered agent name; the generic /agents route requires no such knowledge. The CLI --api-key flag does not constitute a limiting factor in any pre-4.6.58 version - it is the root cause. Exploitation is bounded only by network reachability of the serve port.

Impact

The CVSS 7.3 base score (AV:N/AC:L/PR:N/UI:N) accurately captures the no-prerequisite, network-accessible nature of the bypass, and the published PoC demonstrating live HTTP 200 responses to credentialless requests substantially increases realistic exploitation probability beyond what the score alone conveys. No EPSS data was provided in the source intelligence, and no CISA KEV listing was identified - widespread active exploitation is not confirmed. The most significant real-world risk amplifier is operator deception: the --api-key flag creates a false belief that the service is protected, making operators substantially more likely to expose it on 0.0.0.0 or behind a reverse proxy without additional controls. Downstream agent capabilities - LLM provider credentials, shell and file tools, MCP integrations, RAG/memory systems, browser access - can be fully driven by any unauthenticated caller, meaning the true blast radius depends on what tools each deployed agent instance holds and is not fully captured by the base C:L/I:L/A:L metrics.

Exploit ScenarioDerived

An attacker identifies a host running praisonai serve agents bound to 0.0.0.0 - a common configuration for n8n or webhook integrations - and sends a single unauthenticated POST to /agents/{agent_name} with a JSON body containing an attacker-controlled query string. Because the operator passed --api-key believing the endpoint is protected, no additional firewall or proxy authentication was configured, and the agent executes the query and returns its full response including any tool outputs. A public PoC confirms this exact scenario produces HTTP 200.

This Week Schedule remediation this week. Why: HIGH severity (CVSS 7.0-8.9).
Patch available 0.3% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – Aug 25, 2026

Authentication bypass in PraisonAI's HTTP agent-serving layer allows unauthenticated remote invocation of registered agents despite the operator having configured an API key via --api-key. The root defect is in _create_agents_app(): it never reads config["api_key"] and never attaches a FastAPI Depends() auth dependency to POST /agents and POST /agents/{agent_name}, making the advertised --api-key flag a no-op. A public proof-of-concept confirms HTTP 200 responses to credentialless requests on all agent invocation routes while sibling /api/v1/ routes correctly return 401; no CISA KEV listing was identified at time of analysis.

RemediationAI

Upgrade to PraisonAI v4.6.58 or later by running pip install --upgrade praisonai; this is the vendor-released patch confirmed by release tag v4.6.58 at https://github.com/MervinPraison/PraisonAI/releases/tag/v4.6.58 and patch commit 2f9677abb2ea68eab864ee8b6a828fd0141612e1. If immediate upgrade is not possible, do not bind the serve command to a network-accessible interface: omit --host 0.0.0.0 to restrict to localhost only, limiting exploitation to processes on the same host (trade-off: breaks remote agent integrations such as n8n workflows). Alternatively, place an authenticating reverse proxy in front of the serve port - for example nginx with auth_basic or a bearer token validation module - and firewall direct port access from untrusted networks; this preserves remote access but adds dependency on correct proxy configuration. Under no circumstances should --api-key be treated as a security control in any pre-4.6.58 version; it provides zero enforcement.

Affected VersionsENISA

PraisonAI < 4.6.58

Affected Packages

pypi praisonai fix: 4.6.58

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 1 package in pypi

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Technical ContextAI · show details

PraisonAI (pip/praisonai) is a Python AI agent orchestration framework that exposes a FastAPI HTTP server via praisonai serve agents. The vulnerability class is CWE-306 (Missing Authentication for Critical Function): the CLI argument --api-key is parsed into a config dict by cmd_agents() but the application factory _create_agents_app() imports FastAPI, HTTPException, and Request - notably no Depends, no Header, and no auth middleware - and never consults config["api_key"]. The POST /agents and POST /agents/{agent_name} route handlers call agent.start(query) with no prior credential check. A functioning auth mechanism exists in the same module: praisonai.api.agent_invoke.verify_token guards every /api/v1/... route using Depends(verify_token) and reads from CALL_SERVER_TOKEN environment variable - a completely separate credential path that the --api-key CLI flag never feeds. The disconnect is structural: two credential paths (CLI flag vs env var) targeting two route namespaces (/agents vs /api/v1), with only one path wired to an actual enforcement dependency.

Know when Python gets its next vulnerability

  • Watch products and get an email when something new is published
  • Check this CVE against your own stack and servers
  • Exploit and PoC references, threat intelligence from 22 sources

No credit card · 7-day full trial

Severity by source

Vendor (https://github.com/MervinPraison/PraisonAI) PRIMARY 7.3 HIGH
AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L
vuln.today AI 7.3 HIGH

Network-accessible with no authentication or interaction required; C/I/A held at Low reflecting base agent invocation impact without assuming specific high-privilege tool configurations.

3.1 AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L
4.0 AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N

Primary rating from Vendor (https://github.com/MervinPraison/PraisonAI).

CVSS VectorVendor: https://github.com/MervinPraison/PraisonAI

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
Low
Integrity
Low
Availability
Low

DescriptionCVE.org

Summary

praisonai serve agents exposes HTTP routes that invoke registered agents. The CLI advertises --api-key with help text "API key for authentication", parses it, and forwards it into ServeHandler. But _create_agents_app() never reads config["api_key"] again and installs no auth dependency or middleware on its direct routes. The configured key is a no-op flag.

As a result, an unauthenticated network caller can invoke exposed agents (POST /agents and POST /agents/{agent_name}) even when the operator passed --api-key. Requests with no credentials, a wrong Authorization: Bearer, a wrong X-API-Key, or an empty bearer all reach agent.start().

The failure is made sharper by the fact that a working auth dependency already exists in the same module - praisonai.api.agent_invoke.verify_token guards every /api/v1/... route with Depends(verify_token) and is mounted into the very same app. The direct n8n-compat routes simply do not use it.

Technical Detail

Source-to-sink trace

1. CLI advertises and forwards --api-key:

python
# cli/commands/serve.py
@app.command("agents")
def serve_agents(..., api_key: Optional[str] = typer.Option(None, "--api-key", help="API key for authentication")):
    ...
    if api_key:
        args.extend(["--api-key", api_key])
    exit_code = handle_serve_command(args)

2. cmd_agents() parses api_key into the spec - and that is the last time it is touched:

python
# cli/features/serve.py - cmd_agents()
spec = { ..., "api_key": {"default": None} }
parsed = self._parse_args(args, spec)
app = self._create_agents_app(parsed)

A grep of the entire cli/features/serve.py for api_key returns only the two spec entries (cmd_agents line ~199 and cmd_unified line ~847). config["api_key"] is never read inside _create_agents_app() / _create_unified_app(); it is never compared, and no dependency is attached.

3. _create_agents_app() imports FastAPI, HTTPException, Request - no Depends, no Header, no auth middleware. Every HTTPException raised in the agents routes is 400/404/500 (validation / not-found / execution error); none is 401.

4. Sink - unauthenticated request reaches agent.start():

python
# cli/features/serve.py
@app.post("/agents/{agent_name}")
# n8n compatibility route
async def invoke_single_agent(agent_name: str, request: Request):
    body = await request.json()
    query = body.get("query", "") or body.get("message", "")
    ...
    agent = agent_invoke.get_agent(agent_name)
    result = await loop.run_in_executor(None, agent.start, query)
# no auth anywhere above
    return {"response": str(result)}

@app.post(path)
# default path "/agents"
async def invoke_agents(request: Request, query_data: AgentQuery = None):
    ... agent.start(query) ...

The auth dependency exists - it just isn't applied here

_create_agents_app() mounts the agent_invoke router into the same app:

python
# cli/features/serve.py
if getattr(agent_invoke, 'FASTAPI_AVAILABLE', False) and hasattr(agent_invoke, 'router'):
    app.include_router(agent_invoke.router)

That router properly authenticates every sensitive route:

python
# api/agent_invoke.py
CALL_SERVER_TOKEN = os.getenv('CALL_SERVER_TOKEN')
async def verify_token(request, authorization=Header(None)) -> None:
    ...
    if token != CALL_SERVER_TOKEN:
        raise HTTPException(status_code=401, detail="Unauthorized")

@router.get("/api/v1/agents")
async def list_agents(_: None = Depends(verify_token)): ...
# and register/unregister/info all use it

So in the same process GET /api/v1/agents returns 401 without a token, while POST /agents/{agent_name} returns 200. Note also that verify_token reads the CALL_SERVER_TOKEN env var - not the CLI --api-key - so the CLI option feeds no auth path at all.

Trigger conditions

praisonai serve agents --file agents.yaml --host 0.0.0.0 --port 8765 --api-key expected-secret
POST /agents/{agent_name}   body {"query":"..."}   with no / wrong / empty credentials

Proof of Concept

Built the real _create_agents_app() and exercised it over HTTP via FastAPI TestClient. Only praisonaiagents.Agent is stubbed (.start() returns EXEC:<query>), so no real LLM/credentials. CALL_SERVER_TOKEN=expected-secret was set so the sibling /api/v1 router is genuinely armed - making the contrast explicit.

Operator started with: --api-key expected-secret  (CALL_SERVER_TOKEN also set)

== Sibling /api/v1 route WITH Depends(verify_token) ==
  GET /api/v1/agents [no creds    ] -> HTTP 401
  GET /api/v1/agents [wrong bearer] -> HTTP 401

== Direct agent-invocation route (the bug) ==
  POST /agents/owned [no creds      ] -> HTTP 200  {'response': 'EXEC:hello'}
  POST /agents/owned [wrong bearer  ] -> HTTP 200  {'response': 'EXEC:hello'}
  POST /agents/owned [wrong x-api-key] -> HTTP 200  {'response': 'EXEC:hello'}
  POST /agents/owned [empty bearer  ] -> HTTP 200  {'response': 'EXEC:hello'}
  POST /agents       [no creds      ] -> HTTP 200  {'response': 'EXEC:hi'}

The auth mechanism works for /api/v1 (401) and is entirely absent on the direct /agents routes (200), despite --api-key being configured.

Equivalent HTTP trigger in a fully installed environment

bash
praisonai serve agents --file agents.yaml --host 0.0.0.0 --port 8765 --api-key expected-secret
curl -sS -X POST http://TARGET:8765/agents/owned \
  -H 'Content-Type: application/json' --data-binary '{"query":"hello"}'
# -> 200 {"response":"..."}  (expected: 401 Unauthorized)

Impact

  • Direct primitive: unauthenticated agent invocation despite a configured API key.
  • Misleading control (aggravating): because the CLI advertises --api-key as authentication, operators may deliberately expose the service (e.g. --host 0.0.0.0, reverse proxy, n8n integration) believing it is protected, increasing the real-world likelihood of exposure.
  • Downstream: exposed agents commonly hold LLM provider credentials, RAG/memory, browser/search, MCP, or shell/file tools; the bypass lets an attacker drive those capabilities. Baseline impact is unauthorized LLM cost + access to agent responses.

Suggested Mitigation

  • When config["api_key"] is set, build a shared auth dependency and attach it to every agent-invocation / state-changing route in _create_agents_app() and _create_unified_app() (dependencies=[Depends(verify)]).
  • Reuse / unify with the existing verify_token so the direct /agents routes and the /api/v1 routes share one mechanism, and wire the CLI --api-key into that mechanism (today it feeds nothing; verify_token reads CALL_SERVER_TOKEN).
  • Use constant-time comparison (hmac.compare_digest); verify_token currently uses !=.
  • Update discovery metadata from auth_modes=["none"] to ["api-key","bearer"] for protected endpoints.
  • Regression tests next to tests/unit/test_serve_unified.py: _create_agents_app({"api_key":"secret",...}) → POST /agents/{name} with no creds / wrong Authorization / wrong X-API-Key returns 401; correct key succeeds.
python
import hmac
from fastapi import Header, HTTPException, Depends

def _auth_dependency(expected_key: str):
    async def verify(authorization: str | None = Header(None),
                     x_api_key: str | None = Header(None, alias="X-API-Key")):
        token = x_api_key
        if authorization and authorization.startswith("Bearer "):
            token = authorization[7:]
        if not token or not hmac.compare_digest(token, expected_key):
            raise HTTPException(status_code=401, detail="Unauthorized")
    return Depends(verify)

Executive ViewAI

Why It Matters

PraisonAI's agent invocation endpoints lack functional authentication despite configured API keys (CVE-2026-55538), with publicly available exploit code confirming unrestricted remote agent execution. Organizations with exposed PraisonAI deployments face immediate risk of unauthorized agent access and potential lateral movement or data exfiltration.

Business Impact: Severe
Compensating Controls

Apply vendor patch.

Threat Intelligence Overview

EPSS Score
0.3%
Top 83% exploitable
Prevalence
Low
niche Python AI agent framework, limited enterprise footprint
Threat Intel
1
1 source
Exploit
POC
Public exploit code exists
Data Quality
6 sources
Confidence: High
EUVD NVD CVE.org EPSS Vulnrichment GHSA GitHub

How this decision was reached

The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.

SignalValue
Severity HIGH
CISA KEV No
Public POC Yes
EPSS 0.3%
Patch available Yes
Active threat No
Deciding rule
HIGH severity (CVSS 7.0-8.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision
Out-of-Cycle
Exploitation
Poc
System Exposure· derived
Open
Automatable
Yes
Human Impact
Very High
Technical Impact
Partial

Priority Score

56
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +36
PoC: +20
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

Authentication bypass attacks exploit flaws in the verification mechanisms that control access to systems and applications.

More in Python

View all
CVE-2025-24016 CRITICAL POC
9.9 Feb 10

Wazuh SIEM platform versions 4.4.0 through 4.9.0 contain an unsafe deserialization vulnerability in the DistributedAPI t

CVE-2025-27520 CRITICAL POC
9.8 Apr 04

BentoML version 1.4.2 and earlier contains an unauthenticated remote code execution vulnerability through insecure deser

CVE-2025-2945 CRITICAL POC
9.9 Apr 03

pgAdmin 4 contains critical remote code execution vulnerabilities in the Query Tool download and Cloud Deployment endpoi

CVE-2013-5093 MEDIUM POC
6.8 Sep 27

The renderLocalView function in render/views.py in graphite-web in Graphite 0.9.5 through 0.9.10 uses the pickle Python

CVE-2025-32375 CRITICAL POC
9.8 Apr 09

BentoML is a Python library for building online serving systems optimized for AI apps and model inference. Rated critica

CVE-2014-0224 HIGH POC
7.4 Jun 05

OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph

CVE-2024-21644 HIGH POC
7.5 Jan 08

pyLoad download manager version prior to 0.5.0b3.dev77 exposes the Flask SECRET_KEY through an unauthenticated endpoint.

CVE-2026-33017 CRITICAL POC
9.3 Mar 17

Langflow (a visual LLM pipeline builder) contains a critical unauthenticated code execution vulnerability (CVE-2026-3301

CVE-2017-9462 HIGH POC
8.8 Jun 06

In Mercurial before 4.1.3, "hg serve --stdio" allows remote authenticated users to launch the Python debugger, and conse

CVE-2026-49869 CRITICAL POC
10.0 Jun 26

Unauthenticated remote code execution affects Kestra OSS (the open-source event-driven orchestration platform) prior to

CVE-2026-39987 CRITICAL POC
9.3 Apr 08

Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/

CVE-2024-21645 MEDIUM POC
5.3 Jan 08

pyLoad is the free and open-source Download Manager written in pure Python. Rated medium severity (CVSS 5.3), this vulne

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy