diff --git a/advisories/github-reviewed/2026/06/GHSA-892r-p3jq-jp24/GHSA-892r-p3jq-jp24.json b/advisories/github-reviewed/2026/06/GHSA-892r-p3jq-jp24/GHSA-892r-p3jq-jp24.json index 54c33ef9a100..0263f252cb44 100644 --- a/advisories/github-reviewed/2026/06/GHSA-892r-p3jq-jp24/GHSA-892r-p3jq-jp24.json +++ b/advisories/github-reviewed/2026/06/GHSA-892r-p3jq-jp24/GHSA-892r-p3jq-jp24.json @@ -6,8 +6,8 @@ "aliases": [ "CVE-2026-57116" ], - "summary": "PraisonAI: AgentOS remains unauthenticated after incomplete fix version and allows remote agent invocation", - "details": "# AgentOS remains unauthenticated after GHSA-pm96 patched version and allows remote agent invocation\n\n## Summary\n\nPraisonAI's `AgentOS` FastAPI deployment surface remains unauthenticated in\ncurrent main and in releases after the published patched version for\n`GHSA-pm96-6xpr-978x` / `CVE-2026-40151`.\n\nThe public AgentOS advisory is published as an instruction-disclosure issue\nwith affected versions `< 4.5.128` and patched version `4.5.128`. However,\n`v4.5.128`, latest release `v4.6.57`, and current main still register\n`GET /api/agents` and `POST /api/chat` without authentication. The chat route\ndirectly calls `agent.chat(request.message)`. No-auth and wrong-bearer requests\nboth execute the deployed agent.\n\nThis is broader than passive metadata disclosure. In any deployment where\nAgentOS wraps agents with tools, private context, memory, API integrations, or\ncost-bearing model calls, an unauthenticated reachable client can drive those\nagents.\n\n## Affected Product\n\n- Repository: `MervinPraison/PraisonAI`\n- Package: `praisonai`\n- Component: `src/praisonai/praisonai/app/agentos.py`\n- Config component: `src/praisonai-agents/praisonaiagents/app/config.py`\n- Public advisory incomplete-fix reference: `GHSA-pm96-6xpr-978x` /\n `CVE-2026-40151`\n\nConfirmed affected dynamically:\n\n- `v4.5.126`\n- `v4.5.128` (published patched version for `GHSA-pm96-6xpr-978x`)\n- `v4.6.9`\n- `v4.6.10`\n- `v4.6.56`\n- `v4.6.57`\n- current main `2f9677abb2ea68eab864ee8b6a828fd0141612e1`\n\nStatic source review found the same unauthenticated route pattern and\n`0.0.0.0` default in `v4.2.1`.\n\nSuggested affected range: `>= 4.2.1, <= 4.6.57`.\n\n## Root Cause\n\n`AgentOSConfig` / `AgentAppConfig` defaults the deployment host to all\ninterfaces and has no authentication fields:\n\n```python\nname: str = \"PraisonAI App\"\nhost: str = \"0.0.0.0\"\nport: int = 8000\napi_prefix: str = \"/api\"\n```\n\n`AgentOS._register_routes()` registers public agent metadata and chat routes\nwithout middleware, dependency, API key check, bearer-token check, or startup\nfail-closed guard:\n\n```python\n@app.get(f\"{self.config.api_prefix}/agents\")\nasync def list_agents():\n return {\"agents\": [...]}\n\n@app.post(f\"{self.config.api_prefix}/chat\", response_model=ChatResponse)\nasync def chat(request: ChatRequest):\n ...\n response = agent.chat(request.message)\n```\n\nA wrong `Authorization` header is ignored because the route does not inspect it.\n\nCurrent main also has a root-export bug where `from praisonai import AgentOS`\nraises `ImportError`, but this does not mitigate the issue. The same class\nremains reachable through `from praisonai import AgentApp` and\n`from praisonai.app import AgentOS`.\n\n## Why This Is Not Intended Behavior\n\nPraisonAI's security documentation says API servers were hardened so anonymous\nrequests return `401` and default binding changed from `0.0.0.0` to\n`127.0.0.1` after the prior unauthenticated API server class.\n\nThe API Server Authentication docs say bearer auth is enabled by default,\ndisabling auth is not recommended for production, and `0.0.0.0` should be used\nonly behind an authenticating proxy.\n\nThe local PoV includes a hardened sibling control for the generated deploy API\non current main. It returns:\n\n- no auth: `401`\n- wrong bearer: `401`\n- correct bearer: `200`\n\nAgentOS remains outside that control plane and still accepts no-auth and\nwrong-bearer `/api/chat` requests.\n\n## Local PoV\n\nThe PoV is local-only. It uses FastAPI's in-process test client, a stub agent,\nand a temporary file side effect. It does not start a network listener, call an\nLLM provider, or contact any external service.\n\nCommand:\n\n```bash\nenv PYTHONPATH=\"artifacts/repos/praisonai-current/src/praisonai:artifacts/repos/praisonai-current/src/praisonai-agents\" \\\n uv run --with fastapi --with httpx --with flask --with flask-cors \\\n --with pydantic --with typing-extensions --with rich --with python-dotenv \\\n submission-bundle/praisonai-prai-cand-007-agentos-incomplete-auth-fix/poc/prai_cand_007_agentos_incomplete_auth_fix.py \\\n --repo artifacts/repos/praisonai-current \\\n --label current-head\n```\n\nCurrent-head result summary:\n\n```json\n{\n \"describe\": \"v4.6.57-4-g2f9677ab\",\n \"head\": \"2f9677abb2ea68eab864ee8b6a828fd0141612e1\",\n \"agentos_vulnerable\": true,\n \"entrypoints\": [\n {\n \"entrypoint\": \"agentapp_alias\",\n \"statuses\": [200, 200, 200],\n \"side_effects\": [\"no-auth-marker\", \"wrong-bearer-marker\"]\n },\n {\n \"entrypoint\": \"direct_agentos\",\n \"statuses\": [200, 200, 200],\n \"side_effects\": [\"no-auth-marker\", \"wrong-bearer-marker\"]\n }\n ],\n \"deploy_api_control\": {\n \"control_passed\": true,\n \"statuses\": [401, 401, 200]\n }\n}\n```\n\nThe three AgentOS statuses are for:\n\n- unauthenticated `GET /api/agents`;\n- unauthenticated `POST /api/chat`;\n- wrong-bearer `POST /api/chat`.\n\nThe side-effect list proves both unauthenticated chat requests invoked the\nagent method.\n\nMinimal inline reproducer:\n\n```python\nfrom pathlib import Path\nfrom tempfile import TemporaryDirectory\n\nfrom fastapi.testclient import TestClient\nfrom praisonai import AgentApp\nfrom praisonaiagents import AgentOSConfig\n\nclass StubAgent:\n name = \"pov_agentos_agent\"\n role = \"tester\"\n instructions = \"private instruction marker\"\n\n def __init__(self, out):\n self.out = out\n\n def chat(self, message):\n self.out.write_text(self.out.read_text() + message + \"\\n\")\n return \"PRAI_CAND_007_AGENTOS_EXECUTED:\" + message\n\nwith TemporaryDirectory() as tmp:\n side_effect = Path(tmp) / \"side_effects.txt\"\n side_effect.write_text(\"\")\n app = AgentApp(\n agents=[StubAgent(side_effect)],\n config=AgentOSConfig(host=\"0.0.0.0\", port=8000),\n )\n client = TestClient(app.get_app())\n\n assert client.get(\"/api/agents\").status_code == 200\n assert client.post(\"/api/chat\", json={\"message\": \"no-auth\"}).status_code == 200\n assert client.post(\n \"/api/chat\",\n headers={\"Authorization\": \"Bearer definitely-wrong\"},\n json={\"message\": \"wrong-bearer\"},\n ).status_code == 200\n assert side_effect.read_text().splitlines() == [\"no-auth\", \"wrong-bearer\"]\n```\n\n## Version Sweep\n\n| Target | Result |\n| --- | --- |\n| `v4.5.126` | vulnerable |\n| `v4.5.128` | vulnerable |\n| `v4.6.9` | vulnerable |\n| `v4.6.10` | vulnerable |\n| `v4.6.56` | vulnerable; generated deploy API control returns `401/401/200` |\n| `v4.6.57` | vulnerable; generated deploy API control returns `401/401/200` |\n| current `2f9677abb` | vulnerable; generated deploy API control returns `401/401/200` |\n\nEvidence files are retained locally under the bundle's `evidence/` directory\nand can be provided if useful.\n\n## Duplicate / Incomplete-Fix Notes\n\nThis report is related to `GHSA-pm96-6xpr-978x` / `CVE-2026-40151`. The\npublished advisory describes AgentOS instruction disclosure and lists\n`4.5.128` as patched. It also mentions unauthenticated `/api/chat` as a chained\ninstruction-extraction path.\n\nThe current report should be treated as an incomplete fix / affected-range\ncorrection with a broader demonstrated impact:\n\n- the published patched version `v4.5.128` still reproduces;\n- latest release `v4.6.57` still reproduces;\n- current main still reproduces;\n- the PoV proves unauthorized agent invocation and side effects, not only\n instruction disclosure.\n\nThis is distinct from private `PRAI-CAND-003` / `GHSA-x8cv-xmq7-p8xp`, which\ncovers `praisonaiagents.AgentTeam.launch()` routes. This report covers\n`praisonai.app.AgentOS` and `AgentApp` alias routes.\n\n## Impact\n\nIf an operator exposes an AgentOS app on a reachable interface, any client that\ncan reach it can:\n\n- enumerate deployed agents through `GET /api/agents`;\n- read agent names, roles, and instruction snippets;\n- invoke the default agent or a named agent through `POST /api/chat`;\n- trigger downstream tools, private context reads, memory accesses, API\n integrations, browser actions, or other side effects attached to the agent;\n- consume model/API budget through repeated invocation.\n\nThe exact downstream impact depends on the deployed agents. The framework-level\nboundary failure is that a production deployment surface exposes agent control\nwithout authentication and defaults to binding on all interfaces.\n\n## Suggested Fix\n\nUse the same security model already applied to generated API deployments:\n\n- add authentication fields to `AgentOSConfig` / `AgentAppConfig`;\n- default auth to enabled;\n- default bind host to `127.0.0.1`;\n- reject no-auth and wrong-bearer requests for `GET /api/agents` and\n `POST /api/chat`;\n- fail closed for non-loopback binds unless auth is configured or an explicit\n unsafe development opt-out is set;\n- avoid returning instruction text from unauthenticated metadata endpoints;\n- add regression tests for no auth, wrong bearer, correct bearer, and external\n bind without auth.\n\nMaintainers can either update `GHSA-pm96-6xpr-978x` with the corrected affected\nrange and broader impact or publish a separate incomplete-fix advisory.\n\n## Suggested Severity\n\nSuggested severity: Critical.\n\nThe Critical score matches the unauthenticated agent-control model: network\nattacker, low complexity, no privileges, no user interaction, and high\ndeployment-dependent impact when agents are connected to tools, private data,\nor cost-bearing services. If maintainers score only a minimal no-tool demo\nagent, the impact may be lower, but the current default framework behavior is\nstill unauthenticated agent invocation.", + "summary": "AgentOS Remains Unauthenticated After GHSA-pm96 and Allows Remote Agent Invocation", + "details": "## Summary\n\nPraisonAI's `AgentOS` FastAPI deployment surface remains unauthenticated in current main and in releases after the published patched version for `GHSA-pm96-6xpr-978x` / `CVE-2026-40151`.\n\nThe public AgentOS advisory is published as an instruction-disclosure issue with affected versions `< 4.5.128` and patched version `4.5.128`. However, `v4.5.128`, latest release `v4.6.57`, and current main still register `GET /api/agents` and `POST /api/chat` without authentication. The chat route directly calls `agent.chat(request.message)`. No-auth and wrong-bearer requests both execute the deployed agent.\n\nThis is broader than passive metadata disclosure. In any deployment where AgentOS wraps agents with tools, private context, memory, API integrations, or cost-bearing model calls, an unauthenticated reachable client can drive those agents.\n\n## Technical Details\n\n`AgentOSConfig` / `AgentAppConfig` defaults the deployment host to all interfaces and has no authentication fields:\n\n```python\nname: str = \"PraisonAI App\"\nhost: str = \"0.0.0.0\"\nport: int = 8000\napi_prefix: str = \"/api\"\n```\n\n`AgentOS._register_routes()` registers public agent metadata and chat routes without middleware, dependency, API key check, bearer-token check, or startup fail-closed guard:\n\n```python\n@app.get(f\"{self.config.api_prefix}/agents\")\nasync def list_agents():\n return {\"agents\": [...]}\n\n@app.post(f\"{self.config.api_prefix}/chat\", response_model=ChatResponse)\nasync def chat(request: ChatRequest):\n ...\n response = agent.chat(request.message)\n```\n\nA wrong `Authorization` header is ignored because the route does not inspect it.\n\nCurrent main also has a root-export bug where `from praisonai import AgentOS` raises `ImportError`, but this does not mitigate the issue. The same class remains reachable through `from praisonai import AgentApp` and `from praisonai.app import AgentOS`.\n\n### Why This Is Not Intended Behavior\n\nPraisonAI's security documentation says API servers were hardened so anonymous requests return `401` and default binding changed from `0.0.0.0` to `127.0.0.1` after the prior unauthenticated API server class.\n\nThe API Server Authentication docs say bearer auth is enabled by default, disabling auth is not recommended for production, and `0.0.0.0` should be used only behind an authenticating proxy.\n\nthe PoV includes a hardened sibling control for the generated deploy API on current main. It returns:\n\n- no auth: `401`\n- wrong bearer: `401`\n- correct bearer: `200`\n\nAgentOS remains outside that control plane and still accepts no-auth and wrong-bearer `/api/chat` requests.\n\n## PoV\n\nThe PoV is local-only. It uses FastAPI's in-process test client, a stub agent, and a temporary file side effect. It does not start a network listener, call an model provider, or contact any external service.\n\nCommand:\n\n```bash\nenv PYTHONPATH=\"/path/to/PraisonAI/src/praisonai:/path/to/PraisonAI/src/praisonai-agents\" \\\n uv run --with fastapi --with httpx --with flask --with flask-cors \\\n --with pydantic --with typing-extensions --with rich --with python-dotenv \\\n poc/poc.py \\\n --repo /path/to/PraisonAI \\\n --label current-head\n```\n\nObserved current-head result:\n\n```json\n{\n \"describe\": \"v4.6.57-4-g2f9677ab\",\n \"head\": \"2f9677abb2ea68eab864ee8b6a828fd0141612e1\",\n \"agentos_vulnerable\": true,\n \"entrypoints\": [\n {\n \"entrypoint\": \"agentapp_alias\",\n \"statuses\": [200, 200, 200],\n \"side_effects\": [\"no-auth-marker\", \"wrong-bearer-marker\"]\n },\n {\n \"entrypoint\": \"direct_agentos\",\n \"statuses\": [200, 200, 200],\n \"side_effects\": [\"no-auth-marker\", \"wrong-bearer-marker\"]\n }\n ],\n \"deploy_api_control\": {\n \"control_passed\": true,\n \"statuses\": [401, 401, 200]\n }\n}\n```\n\nThe three AgentOS statuses are for:\n\n- unauthenticated `GET /api/agents`;\n- unauthenticated `POST /api/chat`;\n- wrong-bearer `POST /api/chat`.\n\nThe side-effect list proves both unauthenticated chat requests invoked the agent method.\n\nMinimal inline reproducer:\n\n```python\nfrom pathlib import Path\nfrom tempfile import TemporaryDirectory\n\nfrom fastapi.testclient import TestClient\nfrom praisonai import AgentApp\nfrom praisonaiagents import AgentOSConfig\n\nclass StubAgent:\n name = \"pov_agentos_agent\"\n role = \"tester\"\n instructions = \"private instruction marker\"\n\n def __init__(self, out):\n self.out = out\n\n def chat(self, message):\n self.out.write_text(self.out.read_text() + message + \"\\n\")\n return \"poc:\" + message\n\nwith TemporaryDirectory() as tmp:\n side_effect = Path(tmp) / \"side_effects.txt\"\n side_effect.write_text(\"\")\n app = AgentApp(\n agents=[StubAgent(side_effect)],\n config=AgentOSConfig(host=\"0.0.0.0\", port=8000),\n )\n client = TestClient(app.get_app())\n\n assert client.get(\"/api/agents\").status_code == 200\n assert client.post(\"/api/chat\", json={\"message\": \"no-auth\"}).status_code == 200\n assert client.post(\n \"/api/chat\",\n headers={\"Authorization\": \"Bearer definitely-wrong\"},\n json={\"message\": \"wrong-bearer\"},\n ).status_code == 200\n assert side_effect.read_text().splitlines() == [\"no-auth\", \"wrong-bearer\"]\n```\n\n## PoC\n\nThe PoV section above contains the local reproduction command, input, and decisive output.\n\n## Impact\n\nIf an operator exposes an AgentOS app on a reachable interface, any client that can reach it can:\n\n- enumerate deployed agents through `GET /api/agents`;\n- read agent names, roles, and instruction snippets;\n- invoke the default agent or a named agent through `POST /api/chat`;\n- trigger downstream tools, private context reads, memory accesses, API integrations, browser actions, or other side effects attached to the agent;\n- consume model/API budget through repeated invocation.\n\nThe exact downstream impact depends on the deployed agents. The framework-level boundary failure is that a production deployment surface exposes agent control without authentication and defaults to binding on all interfaces.\n\n### Severity\n\nSuggested severity: Critical.\n\nSuggested CVSS v3.1:\n\n```text\nCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H\n```\n\nSuggested CWEs:\n\n- `CWE-306`: Missing Authentication for Critical Function\n- `CWE-862`: Missing Authorization\n- `CWE-200`: Exposure of Sensitive Information to an Unauthorized Actor\n\nThe Critical score matches the unauthenticated agent-control model: network attacker, low complexity, no privileges, no user interaction, and high deployment-dependent impact when agents are connected to tools, private data, or cost-bearing services. If maintainers score only a minimal no-tool demo agent, the impact may be lower, but the current default framework behavior is still unauthenticated agent invocation.\n\n## Suggested Fix\n\nUse the same security model already applied to generated API deployments:\n\n- add authentication fields to `AgentOSConfig` / `AgentAppConfig`;\n- default auth to enabled;\n- default bind host to `127.0.0.1`;\n- reject no-auth and wrong-bearer requests for `GET /api/agents` and `POST /api/chat`;\n- fail closed for non-loopback binds unless auth is configured or an explicit unsafe development opt-out is set;\n- avoid returning instruction text from unauthenticated metadata endpoints;\n- add regression tests for no auth, wrong bearer, correct bearer, and external bind without auth.\n\nMaintainers can either update `GHSA-pm96-6xpr-978x` with the corrected affected range and broader impact or publish a separate incomplete-fix advisory.\n\n## Affected Package/Versions\n\n- Repository: `MervinPraison/PraisonAI`\n- Package: `praisonai`\n- Component: `src/praisonai/praisonai/app/agentos.py`\n- Config component: `src/praisonai-agents/praisonaiagents/app/config.py`\n- Public advisory incomplete-fix reference: `GHSA-pm96-6xpr-978x` / `CVE-2026-40151`\n\nConfirmed affected dynamically:\n\n- `v4.5.126`\n- `v4.5.128` (published patched version for `GHSA-pm96-6xpr-978x`)\n- `v4.6.9`\n- `v4.6.10`\n- `v4.6.56`\n- `v4.6.57`\n- current main `2f9677abb2ea68eab864ee8b6a828fd0141612e1`\n\nStatic source review found the same unauthenticated route pattern and `0.0.0.0` default in `v4.2.1`.\n\nSuggested affected range: `>= 4.2.1, <= 4.6.57`.\n\n### Version Sweep\n\n| Target | Result |\n| --- | --- |\n| `v4.5.126` | vulnerable |\n| `v4.5.128` | vulnerable |\n| `v4.6.9` | vulnerable |\n| `v4.6.10` | vulnerable |\n| `v4.6.56` | vulnerable; generated deploy API control returns `401/401/200` |\n| `v4.6.57` | vulnerable; generated deploy API control returns `401/401/200` |\n| current `2f9677abb` | vulnerable; generated deploy API control returns `401/401/200` |\n\n## Advisory History\n\nThis report is related to `GHSA-pm96-6xpr-978x` / `CVE-2026-40151`. The published advisory describes AgentOS instruction disclosure and lists `4.5.128` as patched. It also mentions unauthenticated `/api/chat` as a chained instruction-extraction path.\n\nThe current report should be treated as an incomplete fix / affected-range correction with a broader demonstrated impact:\n\n- the published patched version `v4.5.128` still reproduces;\n- latest release `v4.6.57` still reproduces;\n- current main still reproduces;\n- the PoV proves unauthorized agent invocation and side effects, not only instruction disclosure.\n\nThis is distinct from private `GHSA-x8cv-xmq7-p8xp`, which covers `praisonaiagents.AgentTeam.launch()` routes. This report covers `praisonai.app.AgentOS` and `AgentApp` alias routes.\n\n## References\n\n- PraisonAI API Server Authentication: https://docs.praison.ai/docs/features/api-server-auth\n- `GHSA-pm96-6xpr-978x` / `CVE-2026-40151`: https://github.com/advisories/GHSA-pm96-6xpr-978x\n- Legacy generated API server auth advisory: https://github.com/advisories/GHSA-6rmh-7xcm-cpxj\n- Call server unauthenticated agent-control advisory: https://github.com/advisories/GHSA-86qc-r5v2-v6x6\n", "severity": [ { "type": "CVSS_V3", @@ -59,4 +59,4 @@ "github_reviewed_at": "2026-06-18T13:57:47Z", "nvd_published_at": null } -} \ No newline at end of file +}