Every CVE Search/ Get API key

CVE-2026-47396

PraisonAI call server exposes unauthenticated agent listing, invocation, and deletion when CALL_SERVER_TOKEN is unset

9.8 CriticalFix available

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

0.43%Up 0.4 points since Jun 12, 2026
90%50%10%1%

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 CriticalCVSS: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 CriticalCVSS: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:

  1. GET /api/v1/agents returns the list of registered agents.
  2. GET /api/v1/agents/{agent_id} exposes agent metadata and instructions.
  3. POST /api/v1/agents/{agent_id}/invoke executes the registered agent.
  4. 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 CriticalCVSS: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 CriticalCVSS: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 CriticalCVSS: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:

  1. GET /api/v1/agents returns the list of registered agents.
  2. GET /api/v1/agents/{agent_id} exposes agent metadata and instructions.
  3. POST /api/v1/agents/{agent_id}/invoke executes the registered agent.
  4. 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 CriticalCVSS: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:

  1. GET /api/v1/agents returns the list of registered agents.
  2. GET /api/v1/agents/{agent_id} exposes agent metadata and instructions.
  3. POST /api/v1/agents/{agent_id}/invoke executes the registered agent.
  4. 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 CriticalCVSS: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

Affected packages
PackageAffectedFixed
praisonai
PyPI
through 4.6.39
4.6.40
praisonai
PyPI
before 4.6.40, plus listed versions
0.0.10.0.100.0.110.0.120.0.13
Show 45 moreShow less
0.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

History
RecordedChangedSources
aliasesEUVD
first indexedCVE 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

This page doesn't list everything

Left out here: 681 versions and the rest of 3 source descriptions. The JSON record has them.

MoveEnter Open