Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessIdentify network-exposed PraisonAI serve port
-
DeliverySend unauthenticated POST /agents/{name} with arbitrary query payload
-
Exploit_create_agents_app() routes request with no auth checks
-
Executionagent.start() executes attacker-controlled query
-
ImpactReceive 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. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – 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
Affected Packages
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
AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L
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.
Primary rating from Vendor (https://github.com/MervinPraison/PraisonAI).
CVSS VectorVendor: https://github.com/MervinPraison/PraisonAI
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:
# 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:
# 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():
# 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:
# 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:
# 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 itSo 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 credentialsProof 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
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-keyas 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_tokenso the direct/agentsroutes and the/api/v1routes share one mechanism, and wire the CLI--api-keyinto that mechanism (today it feeds nothing;verify_tokenreadsCALL_SERVER_TOKEN). - Use constant-time comparison (
hmac.compare_digest);verify_tokencurrently 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 / wrongAuthorization/ wrongX-API-Keyreturns401; correct key succeeds.
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
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.
Apply vendor patch.
Threat Intelligence Overview
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.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Authentication bypass attacks exploit flaws in the verification mechanisms that control access to systems and applications.
Wazuh SIEM platform versions 4.4.0 through 4.9.0 contain an unsafe deserialization vulnerability in the DistributedAPI t
BentoML version 1.4.2 and earlier contains an unauthenticated remote code execution vulnerability through insecure deser
pgAdmin 4 contains critical remote code execution vulnerabilities in the Query Tool download and Cloud Deployment endpoi
The renderLocalView function in render/views.py in graphite-web in Graphite 0.9.5 through 0.9.10 uses the pickle Python
BentoML is a Python library for building online serving systems optimized for AI apps and model inference. Rated critica
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
pyLoad download manager version prior to 0.5.0b3.dev77 exposes the Flask SECRET_KEY through an unauthenticated endpoint.
Langflow (a visual LLM pipeline builder) contains a critical unauthenticated code execution vulnerability (CVE-2026-3301
In Mercurial before 4.1.3, "hg serve --stdio" allows remote authenticated users to launch the Python debugger, and conse
Unauthenticated remote code execution affects Kestra OSS (the open-source event-driven orchestration platform) prior to
Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/
pyLoad is the free and open-source Download Manager written in pure Python. Rated medium severity (CVSS 5.3), this vulne
EUVD-2026-65514
GHSA-r7v3-x45f-g7hp
NVD
CVE.org
EPSS
Vulnrichment
Exploit-DB