cbcvebase.
CVE-2026-47396
published 2026-05-29

CVE-2026-47396: PraisonAI call server exposes unauthenticated agent listing, invocation, and deletion when CALL_SERVER_TOKEN is unset ### Summary PraisonAI's call server…

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

```python
CALL_SERVER_TOKEN = os.getenv('CALL_SERVER_TOKEN')
```

The authentication dependency then returns successfully when the token is not configured:

```python
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:

```python
@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_to

Affected

1 ranges
VendorProductVersion rangeFixed in
mervinpraisonpraisonai>= 0 < 4.6.404.6.40
Stop checking back — get the weekly exploitation signal.

Every Monday: what got weaponized or added to CISA KEV in the last seven days — each CVE cross-linked to its PoC, Nuclei template, and detection rule. Free, one email a week, unsubscribe in one click.