# PraisonAI: Call API localhost-only authentication bypass via spoofed Host header

PraisonAI's localhost-only guard for PRAISONAI_CALL_AUTH=disabled trusted request.url.hostname, so a spoofed Host: 127.0.0.1 let remote callers list and invoke agents.

- Payout: Research
- Severity: high
- Program: PraisonAI
- Found by: rexpository
- Disclosed: 2026-10-08
- CVE: CVE-2026-61435
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-2gpf-2492-q9jh
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-2gpf-2492-q9jh
- Tags: area:ai domain:ai domain:api impact:internal-access kind:research platform:ghsa sev:high tech:python tech:rest technique:incomplete-fix technique:source-review vuln:access-control vuln:auth-bypass vuln:host-header

**Target:** FastAPI /api/v1/agents call/serve API (agent_invoke.verify_token)
**Root cause:** The disabled-auth localhost restriction derived bind safety from request.url.hostname, which comes from the client-controlled Host header, instead of a server-owned startup/socket property.
**Steps:**
1. Set PRAISONAI_CALL_AUTH=disabled and mount agent_invoke.router in a FastAPI app reachable externally.
2. Send `GET /api/v1/agents` with `Host: external.example` -> 503 (guard rejects).
3. Send `GET /api/v1/agents` with `Host: 127.0.0.1` -> 200, agent list returned.
4. Send `POST /api/v1/agents/pov-agent/invoke` with `Host: 127.0.0.1` and body `{"message": "host-header-bypass"}` -> 200, agent executes.
**How found:** Reporter reviewed the patch for the prior unconditional disabled-auth bypass (GHSA-8ccj-p46r-jwqq) and noticed the new guard reads request.url.hostname, a Host-header-derived value, then built an in-process FastAPI PoV with negative controls (no-token and external Host) to confirm only the spoofed Host passes.
**Exploitation:** Unauthenticated network attacker sends requests with a spoofed `Host: 127.0.0.1` header to a PraisonAI call/serve API running with PRAISONAI_CALL_AUTH=disabled; verify_token() sees a 'localhost' hostname and returns, letting the attacker enumerate registered agents and invoke them via /api/v1/agents/{agent_id}/invoke, running agent tools/model calls.
**Escalation:** Bypass covers the whole /api/v1/agents router family; invoked agents may hold tools, private context, file/browser/API access and paid model access, raising impact beyond the PoV stub.
**Insight:** When auditing fixes for auth opt-outs, check whether 'is this local?' is decided from request metadata (Host, X-Forwarded-For, Origin) rather than the actual bind address; a patched guard that reads request.url.hostname is still bypassable with a single header.

