2026-07-11 · view entry permalink →
PraisonAI agent framework: three CVEs — unsandboxed LLM code execution, tool-call RCE, and vector-store DDL injection
Three CVEs were published together on 2026-07-11 (NVD/EUVD) in PraisonAI — an open-source multi-agent LLM orchestration framework distributed as the praisonaiagents and praisonai pip packages. The first two share one root cause: the framework treats model output as trusted, so an attacker who can influence the LLM (via prompt injection in agent input, ingested documents, or tool results) reaches code execution without touching a classic network listener. CVE-2026-61447 (CVSS 10.0) is in CodeAgent._execute_python() (src/praisonai-agents/praisonaiagents/agent/code_agent.py, lines 253–308): LLM-generated Python is written to a temp file and run via subprocess.run(["python", temp_file], env=os.environ.copy()) with no AST validation and no import restrictions, and CodeConfig declares sandbox: bool = True (line 21) that the execution path never reads — so the flag is inert and the subprocess inherits every credential in the parent environment (OPENAI_API_KEY, DATABASE_URL, cloud tokens) (PraisonAI GHSA-2xv2-w8cq-5gxw, 2026-06-25). The advisory contrasts this with the framework's own sandboxed execute_code tool, which runs with an empty environment.
CVE-2026-61445 (CVSS 9.4) is in the AICoder chat-UI component, which exposes write_to_file and execute_command tools to the model with no path validation or command sanitization; apply_llm_response joins the caller path with os.path.join(self.cwd, args["path"]), which does not block absolute paths, so a model-driven write can land at /etc/crontab or /root/.ssh/authorized_keys, and the advisory notes containers commonly run as root, turning tool-call abuse into full in-container compromise (PraisonAI GHSA-9mp3-24cc-77mg, 2026-06-25). CVE-2026-60090 (CVSS 9.3) is a different bug class with no LLM nexus — a classic SQL/CQL injection reachable by any caller who can influence collection-creation parameters (for example through a RAG ingestion API), not through the model: the PGVector and Cassandra knowledge-store backends validate schema/keyspace/collection identifiers but interpolate the caller-supplied dimension value straight into the CREATE TABLE/CQL vector-column DDL, and the int type hint is not enforced at runtime, so a value like 3); DROP TABLE tenant_secrets; -- reaches the database driver (PraisonAI GHSA-wf65-4jjx-q444, 2026-06-25). The three CVEs — VulnCheck-assigned and carried on ENISA EUVD and NVD with CVSS 4.0 vectors consistent with the assigned scores — were also independently re-reported the same day (TheHackerWire, 2026-07-11).
The exposure is narrow — self-hosted agent deployments, most likely in AI-pilot and innovation teams rather than production estate — but the transferable lesson is in the first two bugs: in an agentic framework the model's output is an execution surface, so the same detection thinking applies to any self-hosted LLM/agent tooling (CVE-2026-60090 is a conventional injection that the usual input-validation hygiene covers). Detection concepts, telemetry-class first: in process-creation telemetry with parent lineage (Sysmon EID 1, auditd execve, EDR process events), surface script interpreters (python, sh) whose parent is the agent-hosting Python process — and, more discriminating, where that child then reads credential-shaped environment variables or opens outbound connections; in the framework's own tool-call audit log, flag write_to_file / execute_command invocations whose arguments point outside the declared workspace (/etc/, ~/.ssh/, cron paths); and in database audit logs, flag knowledge-store DDL carrying non-integer tokens (semicolons, comment sequences) in the vector-dimension position.
CodeAgent._execute_python() executes LLM-generated Python code in a subprocess with the complete parent-process environment (os.environ.copy()), zero AST validation, zero import restrictions, and no sandbox enforcement — even when CodeConfig(sandbox=True) is explicitly set.
sandbox=True is dead code
**Root access**: All Docker containers run as root (no USER directive)
A caller that can influence collection creation dimensions can append SQL/CQL tokens to the generated DDL executed by the database driver.