CVE-2026-47396
PraisonAI call server exposes unauthenticated agent listing, invocation, and deletion when CALL_SERVER_TOKEN is unset
PraisonAI is a multi-agent teams system. Prior to version 4.6.40, PraisonAI's call server exposes a network-facing agent control API without authentication when CALL_SERVER_TOKEN is not configured. The affected component is the praisonai.api.agent_invoke router as mounted by praisonai.api.call. The authentication helper verify_token() fails open when CALL_SERVER_TOKEN is unset. Since every sensitive agent-control endpoint depends on this helper, starting the call server without a token allows any reachable client to list agents, inspect agent metadata and instructions, invoke agents, and unregister agents. This is security-relevant because the bundled call server includes the vulnerable router and binds to 0.0.0.0. As a result, operators who launch the call server without explicitly setting CALL_SERVER_TOKEN may unintentionally expose an unauthenticated remote agent control plane. Version 4.6.40 fixes the issue.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- High
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
9.8
PraisonAI call server exposes unauthenticated agent listing, invocation, and deletion when CALL_SERVER_TOKEN is unset
PraisonAI is a multi-agent teams system. Prior to version 4.6.40, PraisonAI's call server exposes a network-facing agent control API without authentication when CALL_SERVER_TOKEN is not configured. The affected component is the praisonai.api.agent_invoke router as mounted by praisonai.api.call. The authentication helper verify_token() fails open when CALL_SERVER_TOKEN is unset. Since every sensitive agent-control endpoint depends on this helper, starting the call server without a token allows any reachable client to list agents, inspect agent metadata and instructions, invoke agents, and unregister agents. This is security-relevant because the bundled call server includes the vulnerable router and binds to 0.0.0.0. As a result, operators who launch the call server without explicitly setting CALL_SERVER_TOKEN may unintentionally expose an unauthenticated remote agent control plane. Version 4.6.40 fixes the issue.
- Record
CVE-2026-47396- CVSS 3.1
- 9.8 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-284, CWE-306
- Updated
- 2026-11-02
EUVDEUVD-2026-46304
9.8
PraisonAI is a multi-agent teams system. Prior to version 4.6.40, PraisonAI's call server exposes a network-facing agent control API without authentication when CALL_SERVER_TOKEN is not configured. The affected component is the praisonai.api.agent_invoke router as mounted by praisonai.api.call. The authentication helper verify_token() fails open when CALL_SERVER_TOKEN is unset. Since every sensitive agent-control endpoint depends on this helper, starting the call server without a token allows any reachable client to list agents, inspect agent metadata and instructions, invoke agents, and unregister agents. This is security-relevant because the bundled call server includes the vulnerable router and binds to 0.0.0.0. As a result, operators who launch the call server without explicitly setting CALL_SERVER_TOKEN may unintentionally expose an unauthenticated remote agent control plane. Version 4.6.40 fixes the issue.
- Record
EUVD-2026-46304- CVSS 3.1
- 9.8 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-86qc-r5v2-v6x6
9.8
PraisonAI call server exposes unauthenticated agent listing, invocation, and deletion when CALL_SERVER_TOKEN is unset
Summary
PraisonAI's call server exposes a network-facing agent control API without authentication when CALL_SERVER_TOKEN is not configured.
The affected component is the praisonai.api.agent_invoke router as mounted by praisonai.api.call. The authentication helper verify_token() fails open when CALL_SERVER_TOKEN is unset. Since every sensitive agent-control endpoint depends on this helper, starting the call server without a token allows any reachable client to list agents, inspect agent metadata and instructions, invoke agents, and unregister agents.
This is security-relevant because the bundled call server includes the vulnerable router and binds to 0.0.0.0. As a result, operators who launch the call server without explicitly setting CALL_SERVER_TOKEN may unintentionally expose an unauthenticated remote agent control plane.
Details
The vulnerable behavior is caused by a fail-open authentication default.
In praisonai/api/agent_invoke.py, CALL_SERVER_TOKEN is read from the environment:
CALL_SERVER_TOKEN = os.getenv('CALL_SERVER_TOKEN')
The authentication dependency then returns successfully when the token is not configured:
async def verify_token(request: Request, authorization: Optional[str] = Header(None)) -> None:
if not FASTAPI_AVAILABLE or not CALL_SERVER_TOKEN:
return # No authentication if FastAPI unavailable or no token set
This means that the absence of CALL_SERVER_TOKEN disables authentication entirely.
The same helper is used by sensitive agent-control routes, including:
@router.post("/agents/{agent_id}/invoke")
async def invoke_agent(..., _: None = Depends(verify_token))
@router.get("/agents")
async def list_agents(_: None = Depends(verify_token))
@router.delete("/agents/{agent_id}")
async def unregister_agent_endpoint(agent_id: str, _: None = Depends(verify_token))
@router.get("/agents/{agent_id}")
async def get_agent_info(agent_id: str, _: None = Depends(verify_token))
These endpoints allow a caller to:
- list registered agents;
- retrieve agent metadata;
- retrieve agent instruction text;
- invoke agents;
- unregister agents.
The vulnerable router is mounted by the call server:
from .agent_invoke import router as agent_invoke_router
app.include_router(agent_invoke_router)
The call server then listens on all interfaces:
uvicorn.run(app, host="0.0.0.0", port=port, log_level="warning")
Therefore, when praisonai-call is started without CALL_SERVER_TOKEN, the agent-control API becomes reachable without authentication from any client that can access the server.
PoC
The following local PoC imports the real praisonai.api.agent_invoke router from source, ensures CALL_SERVER_TOKEN is absent, registers a demo agent, mounts the router into a local FastAPI app, and sends unauthenticated requests to the vulnerable endpoints.
The PoC proves that, without sending any authentication material:
GET /api/v1/agentsreturns the list of registered agents.GET /api/v1/agents/{agent_id}exposes agent metadata and instructions.POST /api/v1/agents/{agent_id}/invokeexecutes the registered agent.DELETE /api/v1/agents/{agent_id}unregisters the agent.
Run with:
PRAISONAI_REPO=/path/to/PraisonAI python -B embedded_poc.py
Full PoC:
#!/usr/bin/env python3
from __future__ import annotations
import os
import sys
from pathlib import Path
from types import SimpleNamespace
REPO_ROOT = Path(os.environ.get("PRAISONAI_REPO", "/path/to/PraisonAI")).resolve()
PRAISON_ROOT = REPO_ROOT / "src" / "praisonai"
def verify_source() -> None:
expected = {
PRAISON_ROOT / "praisonai/api/agent_invoke.py": [
"CALL_SERVER_TOKEN = os.getenv('CALL_SERVER_TOKEN')",
"if not FASTAPI_AVAILABLE or not CALL_SERVER_TOKEN:",
'@router.post("/agents/{agent_id}/invoke")',
'@router.get("/agents")',
…
- Record
GHSA-86qc-r5v2-v6x6- CVSS 3.1
- 9.8 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-284, CWE-306
- Updated
- 2026-11-02
NVD
9.8
PraisonAI is a multi-agent teams system. Prior to version 4.6.40, PraisonAI's call server exposes a network-facing agent control API without authentication when CALL_SERVER_TOKEN is not configured. The affected component is the praisonai.api.agent_invoke router as mounted by praisonai.api.call. The authentication helper verify_token() fails open when CALL_SERVER_TOKEN is unset. Since every sensitive agent-control endpoint depends on this helper, starting the call server without a token allows any reachable client to list agents, inspect agent metadata and instructions, invoke agents, and unregister agents. This is security-relevant because the bundled call server includes the vulnerable router and binds to 0.0.0.0. As a result, operators who launch the call server without explicitly setting CALL_SERVER_TOKEN may unintentionally expose an unauthenticated remote agent control plane. Version 4.6.40 fixes the issue.
- Record
CVE-2026-47396- CVSS 3.1
- 9.8 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-284, CWE-306
- Updated
- 2026-11-02
OSV
9.8
PraisonAI call server exposes unauthenticated agent listing, invocation, and deletion when CALL_SERVER_TOKEN is unset
PraisonAI is a multi-agent teams system. Prior to version 4.6.40, PraisonAI's call server exposes a network-facing agent control API without authentication when CALL_SERVER_TOKEN is not configured. The affected component is the praisonai.api.agent_invoke router as mounted by praisonai.api.call. The authentication helper verify_token() fails open when CALL_SERVER_TOKEN is unset. Since every sensitive agent-control endpoint depends on this helper, starting the call server without a token allows any reachable client to list agents, inspect agent metadata and instructions, invoke agents, and unregister agents. This is security-relevant because the bundled call server includes the vulnerable router and binds to 0.0.0.0. As a result, operators who launch the call server without explicitly setting CALL_SERVER_TOKEN may unintentionally expose an unauthenticated remote agent control plane. Version 4.6.40 fixes the issue.
- Record
CVE-2026-47396- CVSS 3.1
- 9.8 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-284, CWE-306
- Updated
- 2026-11-02
OSVGHSA-86qc-r5v2-v6x6
9.8
PraisonAI call server exposes unauthenticated agent listing, invocation, and deletion when CALL_SERVER_TOKEN is unset
Summary
PraisonAI's call server exposes a network-facing agent control API without authentication when CALL_SERVER_TOKEN is not configured.
The affected component is the praisonai.api.agent_invoke router as mounted by praisonai.api.call. The authentication helper verify_token() fails open when CALL_SERVER_TOKEN is unset. Since every sensitive agent-control endpoint depends on this helper, starting the call server without a token allows any reachable client to list agents, inspect agent metadata and instructions, invoke agents, and unregister agents.
This is security-relevant because the bundled call server includes the vulnerable router and binds to 0.0.0.0. As a result, operators who launch the call server without explicitly setting CALL_SERVER_TOKEN may unintentionally expose an unauthenticated remote agent control plane.
Details
The vulnerable behavior is caused by a fail-open authentication default.
In praisonai/api/agent_invoke.py, CALL_SERVER_TOKEN is read from the environment:
CALL_SERVER_TOKEN = os.getenv('CALL_SERVER_TOKEN')
The authentication dependency then returns successfully when the token is not configured:
async def verify_token(request: Request, authorization: Optional[str] = Header(None)) -> None:
if not FASTAPI_AVAILABLE or not CALL_SERVER_TOKEN:
return # No authentication if FastAPI unavailable or no token set
This means that the absence of CALL_SERVER_TOKEN disables authentication entirely.
The same helper is used by sensitive agent-control routes, including:
@router.post("/agents/{agent_id}/invoke")
async def invoke_agent(..., _: None = Depends(verify_token))
@router.get("/agents")
async def list_agents(_: None = Depends(verify_token))
@router.delete("/agents/{agent_id}")
async def unregister_agent_endpoint(agent_id: str, _: None = Depends(verify_token))
@router.get("/agents/{agent_id}")
async def get_agent_info(agent_id: str, _: None = Depends(verify_token))
These endpoints allow a caller to:
- list registered agents;
- retrieve agent metadata;
- retrieve agent instruction text;
- invoke agents;
- unregister agents.
The vulnerable router is mounted by the call server:
from .agent_invoke import router as agent_invoke_router
app.include_router(agent_invoke_router)
The call server then listens on all interfaces:
uvicorn.run(app, host="0.0.0.0", port=port, log_level="warning")
Therefore, when praisonai-call is started without CALL_SERVER_TOKEN, the agent-control API becomes reachable without authentication from any client that can access the server.
PoC
The following local PoC imports the real praisonai.api.agent_invoke router from source, ensures CALL_SERVER_TOKEN is absent, registers a demo agent, mounts the router into a local FastAPI app, and sends unauthenticated requests to the vulnerable endpoints.
The PoC proves that, without sending any authentication material:
GET /api/v1/agentsreturns the list of registered agents.GET /api/v1/agents/{agent_id}exposes agent metadata and instructions.POST /api/v1/agents/{agent_id}/invokeexecutes the registered agent.DELETE /api/v1/agents/{agent_id}unregisters the agent.
Run with:
PRAISONAI_REPO=/path/to/PraisonAI python -B embedded_poc.py
Full PoC:
#!/usr/bin/env python3
from __future__ import annotations
import os
import sys
from pathlib import Path
from types import SimpleNamespace
REPO_ROOT = Path(os.environ.get("PRAISONAI_REPO", "/path/to/PraisonAI")).resolve()
PRAISON_ROOT = REPO_ROOT / "src" / "praisonai"
def verify_source() -> None:
expected = {
PRAISON_ROOT / "praisonai/api/agent_invoke.py": [
"CALL_SERVER_TOKEN = os.getenv('CALL_SERVER_TOKEN')",
"if not FASTAPI_AVAILABLE or not CALL_SERVER_TOKEN:",
'@router.post("/agents/{agent_id}/invoke")',
'@router.get("/agents")',
…
- Record
GHSA-86qc-r5v2-v6x6- CVSS 3.1
- 9.8 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-284, CWE-306
- Updated
- 2026-11-02
OSVPYSEC-2026-466
9.8
PraisonAI call server exposes unauthenticated agent listing, invocation, and deletion when CALL_SERVER_TOKEN is unset
Summary
PraisonAI's call server exposes a network-facing agent control API without authentication when CALL_SERVER_TOKEN is not configured.
The affected component is the praisonai.api.agent_invoke router as mounted by praisonai.api.call. The authentication helper verify_token() fails open when CALL_SERVER_TOKEN is unset. Since every sensitive agent-control endpoint depends on this helper, starting the call server without a token allows any reachable client to list agents, inspect agent metadata and instructions, invoke agents, and unregister agents.
This is security-relevant because the bundled call server includes the vulnerable router and binds to 0.0.0.0. As a result, operators who launch the call server without explicitly setting CALL_SERVER_TOKEN may unintentionally expose an unauthenticated remote agent control plane.
Details
The vulnerable behavior is caused by a fail-open authentication default.
In praisonai/api/agent_invoke.py, CALL_SERVER_TOKEN is read from the environment:
CALL_SERVER_TOKEN = os.getenv('CALL_SERVER_TOKEN')
The authentication dependency then returns successfully when the token is not configured:
async def verify_token(request: Request, authorization: Optional[str] = Header(None)) -> None:
if not FASTAPI_AVAILABLE or not CALL_SERVER_TOKEN:
return # No authentication if FastAPI unavailable or no token set
This means that the absence of CALL_SERVER_TOKEN disables authentication entirely.
The same helper is used by sensitive agent-control routes, including:
@router.post("/agents/{agent_id}/invoke")
async def invoke_agent(..., _: None = Depends(verify_token))
@router.get("/agents")
async def list_agents(_: None = Depends(verify_token))
@router.delete("/agents/{agent_id}")
async def unregister_agent_endpoint(agent_id: str, _: None = Depends(verify_token))
@router.get("/agents/{agent_id}")
async def get_agent_info(agent_id: str, _: None = Depends(verify_token))
These endpoints allow a caller to:
- list registered agents;
- retrieve agent metadata;
- retrieve agent instruction text;
- invoke agents;
- unregister agents.
The vulnerable router is mounted by the call server:
from .agent_invoke import router as agent_invoke_router
app.include_router(agent_invoke_router)
The call server then listens on all interfaces:
uvicorn.run(app, host="0.0.0.0", port=port, log_level="warning")
Therefore, when praisonai-call is started without CALL_SERVER_TOKEN, the agent-control API becomes reachable without authentication from any client that can access the server.
PoC
The following local PoC imports the real praisonai.api.agent_invoke router from source, ensures CALL_SERVER_TOKEN is absent, registers a demo agent, mounts the router into a local FastAPI app, and sends unauthenticated requests to the vulnerable endpoints.
The PoC proves that, without sending any authentication material:
GET /api/v1/agentsreturns the list of registered agents.GET /api/v1/agents/{agent_id}exposes agent metadata and instructions.POST /api/v1/agents/{agent_id}/invokeexecutes the registered agent.DELETE /api/v1/agents/{agent_id}unregisters the agent.
Run with:
PRAISONAI_REPO=/path/to/PraisonAI python -B embedded_poc.py
Full PoC:
#!/usr/bin/env python3
from __future__ import annotations
import os
import sys
from pathlib import Path
from types import SimpleNamespace
REPO_ROOT = Path(os.environ.get("PRAISONAI_REPO", "/path/to/PraisonAI")).resolve()
PRAISON_ROOT = REPO_ROOT / "src" / "praisonai"
def verify_source() -> None:
expected = {
PRAISON_ROOT / "praisonai/api/agent_invoke.py": [
"CALL_SERVER_TOKEN = os.getenv('CALL_SERVER_TOKEN')",
"if not FASTAPI_AVAILABLE or not CALL_SERVER_TOKEN:",
'@router.post("/agents/{agent_id}/invoke")',
'@router.get("/agents")',
…
- Record
PYSEC-2026-466- CVSS 3.1
- 9.8 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H - Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
praisonaiPyPI |
through 4.6.39 | 4.6.40 |
praisonaiPyPI |
before 4.6.40, plus listed versions 0.0.10.0.100.0.110.0.120.0.13 Show 45 moreShow less0.0.140.0.150.0.160.0.170.0.180.0.190.0.20.0.200.0.210.0.220.0.230.0.240.0.250.0.260.0.270.0.280.0.290.0.30.0.300.0.310.0.320.0.330.0.340.0.350.0.360.0.370.0.380.0.390.0.40.0.400.0.410.0.420.0.430.0.440.0.450.0.460.0.470.0.480.0.490.0.50.0.500.0.520.0.530.0.540.0.55 |
4.6.40 |
History
| Recorded | Changed | Sources |
|---|---|---|
| aliases | EUVD | |
| first indexed | CVE List, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-47396 is a critical vulnerability (CVSS 9.8) in Mervinpraison Praisonai, published May 29, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.43%, the 38th percentile. Fixed in praisonai 4.6.40.
References
github.com/MervinPraison/PraisonAI/security/advisories/GHSA-86qc-r5v2-v6x6
github.com/MervinPraison/PraisonAI/commit/ef79b7a0561796ad9807f0f09538c25cc78d3619
github.com/advisories/GHSA-86qc-r5v2-v6x6
github.com/CVEProject/cvelistV5/tree/main/cves/2026/47xxx/CVE-2026-47396.json
nvd.nist.gov/vuln/detail/CVE-2026-47396
github.com/MervinPraison/PraisonAI
pypi.org/project/praisonai
Left out here: 681 versions and the rest of 3 source descriptions. The JSON record has them.