Critical
github
·
GHSA-4869-x4pr-q22x
PraisonAI: Unauthenticated RCE via Jobs API + Approval Bypass
Published Jun 18, 2026
CVSS 9.8
Unauthenticated Remote Code Execution via Jobs API and Approval Bypass in PraisonAI
Summary
An unauthenticated attacker can execute arbitrary OS commands on any server running
the PraisonAI Jobs API by submitting a crafted workflow YAML. The attack chains two
weaknesses: the /api/v1/runs endpoint requires no credentials, and a top-level
approve field in the submitted YAML unconditionally bypasses the
@require_approval safety decorator on dangerous tools such as execute_command.
Ecosystem: pip | Package: praisonai | Affected: ` depends on the configured LLM following the injected instruction, which is
reliably triggered on any instruction-tuned model.
Attack Chain
Attacker (unauthenticated)
│
├─ POST /api/v1/runs (no auth check)
│ └─ agent_yaml: approve: [execute_command]
│
├─ yaml_parser.py:261
│ └─ approve_tools = ["execute_command"]
│
├─ workflows.py:1025
│ └─ set_yaml_approved_tools(["execute_command"])
│
├─ LLM follows backstory instruction → calls execute_command("curl ...")
│
├─ approval/__init__.py:179
│ └─ is_yaml_approved("execute_command") → True → BYPASSED
│
└─ shell_tools.py:33 → subprocess.Popen(["curl", ...])
└─ ARBITRARY COMMAND EXECUTION
Affected Components
| File | Line | Issue |
|---|---|---|
src/praisonai/praisonai/jobs/router.py |
47 | No Depends(verify_token) on submit_job |
src/praisonai/praisonai/jobs/models.py |
30 | agent_yaml accepted from unauthenticated caller |
src/praisonai-agents/praisonaiagents/workflows/yaml_parser.py |
261 | approve YAML field loaded without restriction |
src/praisonai-agents/praisonaiagents/workflows/yaml_parser.py |
370 | Sets workflow.approve_tools from YAML |
src/praisonai-agents/praisonaiagents/workflows/workflows.py |
1025–1028 | set_yaml_approved_tools() disables approval check |
src/praisonai-agents/praisonaiagents/approval/__init__.py |
179–180 | is_yaml_approved() bypass in decorator |
src/praisonai-agents/praisonaiagents/tools/shell_tools.py |
33 | subprocess.Popen execution |
Impact
Full unauthenticated remote code execution on any host running the Jobs API. No credentials, no existing session, and no operator interaction required.
Recommended Fixes
Fix 1 — Add authentication to the Jobs API (Critical)
# src/praisonai/praisonai/jobs/router.py
from .auth import verify_token
@router.post("")
async def submit_job(
body: JobSubmitRequest,
_: None = Depends(verify_token), # add this
...
):
Fix 2 — Remove or restrict the approve YAML field (Critical)
# src/praisonai-agents/praisonaiagents/workflows/yaml_parser.py:261
# Option A: remove entirely
approve_tools = []
# Option B: allowlist only non-dangerous tools
SAFE_TO_APPROVE = {"web_search", "read_file", "write_file"}
approve_tools = [t for t in data.get('approve', []) if t in SAFE_TO_APPROVE]
Affected AI Products
gpt-4
llm