{"id":"CVE-2026-34935","aliases":["EUVD-2026-18913","GHSA-9gm9-c8mq-vq7m","PYSEC-2026-471"],"status":"published","title":"PraisonAI: OS Command Injection in MCPHandler.parse_mcp_command()","description":"PraisonAI is a multi-agent teams system. From version 4.5.15 to before version 4.5.69, the --mcp CLI argument is passed directly to shlex.split() and forwarded through the call chain to anyio.open_process() with no validation, allowlist check, or sanitization at any hop, allowing arbitrary OS command execution as the process user. This issue has been patched in version 4.5.69.","severity":{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-10","score":0.00839,"percentile":0.58118,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-78"],"published":"2026-04-01T23:20:00Z","modified":"2026-10-28T02:30:20Z","fixes":[{"ecosystem":"PyPI","package":"praisonai","fixed_in":["4.5.69"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"PyPI","package":"praisonai","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"4.5.15"},{"last_affected":"4.5.68"},{"fixed":"4.5.69"}]}]},{"source":"osv","ecosystem":"PyPI","package":"praisonai","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"4.5.15"},{"fixed":"4.5.69"}]}],"versions":["4.5.15","4.5.16","4.5.18","4.5.19","4.5.20","4.5.21","4.5.22","4.5.23","4.5.24","4.5.25","4.5.26","4.5.27","4.5.28","4.5.29","4.5.30","4.5.31","4.5.32","4.5.33","4.5.34","4.5.35","4.5.36","4.5.37","4.5.38","4.5.39","4.5.40","4.5.41","4.5.42","4.5.43","4.5.44","4.5.45","4.5.46","4.5.48","4.5.49","4.5.51","4.5.52","4.5.54","4.5.55","4.5.56","4.5.57","4.5.58","4.5.59","4.5.60","4.5.62","4.5.63","4.5.64","4.5.65","4.5.67","4.5.68"]},{"source":"osv","ecosystem":"PyPI","package":"praisonai","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"4.5.15"},{"fixed":"4.5.69"}]}],"versions":["4.5.15","4.5.16","4.5.18","4.5.19","4.5.20","4.5.21","4.5.22","4.5.23","4.5.24","4.5.25","4.5.26","4.5.27","4.5.28","4.5.29","4.5.30","4.5.31","4.5.32","4.5.33","4.5.34","4.5.35","4.5.36","4.5.37","4.5.38","4.5.39","4.5.40","4.5.41","4.5.42","4.5.43","4.5.44","4.5.45","4.5.46","4.5.48","4.5.49","4.5.51","4.5.52","4.5.54","4.5.55","4.5.56","4.5.57","4.5.58","4.5.59","4.5.60","4.5.62","4.5.63","4.5.64","4.5.65","4.5.67","4.5.68"]}],"products":[{"vendor":"mervinpraison","product":"praisonai"},{"vendor":"praison","product":"praisonai"}],"references":[{"url":"https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-9gm9-c8mq-vq7m","tags":["x_refsource_CONFIRM","Exploit","Vendor Advisory","advisory","web"]},{"url":"https://github.com/MervinPraison/PraisonAI/commit/47bff65413beaa3c21bf633c1fae4e684348368c","tags":["x_refsource_MISC","Patch","fix","web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-34935","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-9gm9-c8mq-vq7m","tags":["advisory"]},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/34xxx/CVE-2026-34935.json","tags":["advisory"]},{"url":"https://github.com/MervinPraison/PraisonAI","tags":["package"]},{"url":"https://pypi.org/project/praisonai","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-34935","title":"PraisonAI: OS Command Injection in MCPHandler.parse_mcp_command()","description":"PraisonAI is a multi-agent teams system. From version 4.5.15 to before version 4.5.69, the --mcp CLI argument is passed directly to shlex.split() and forwarded through the call chain to anyio.open_process() with no validation, allowlist check, or sanitization at any hop, allowing arbitrary OS command execution as the process user. This issue has been patched in version 4.5.69.","status":"published","published":"2026-04-03T22:48:21.261Z","modified":"2026-04-06T19:04:26.478Z","cvss":[{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical","assessor":"cna"}],"cwes":["CWE-78"],"updated_at":"2026-11-02T14:20:14.302133Z"}],"euvd":[{"id":"EUVD-2026-18913","description":"PraisonAI is a multi-agent teams system. From version 4.5.15 to before version 4.5.69, the --mcp CLI argument is passed directly to shlex.split() and forwarded through the call chain to anyio.open_process() with no validation, allowlist check, or sanitization at any hop, allowing arbitrary OS command execution as the process user. This issue has been patched in version 4.5.69.","status":"published","published":"2026-04-03T22:48:21Z","modified":"2026-04-06T19:04:26Z","cvss":[{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical"}],"updated_at":"2026-11-02T19:25:15.380284Z"}],"ghsa":[{"id":"GHSA-9gm9-c8mq-vq7m","title":"PraisonAI: OS Command Injection in MCPHandler.parse_mcp_command()","description":"### Summary\n\nThe `--mcp` CLI argument is passed directly to `shlex.split()` and forwarded through the call chain to `anyio.open_process()` with no validation, allowlist check, or sanitization at any hop, allowing arbitrary OS command execution as the process user.\n\n### Details\n\n`cli/features/mcp.py:61` (source) -\u003e `praisonaiagents/mcp/mcp.py:345` (hop) -\u003e `mcp/client/stdio/__init__.py:253` (sink)\n```python\n# source\nparts = shlex.split(command)\n\n# hop\ncmd, args, env = self.parse_mcp_command(command, env_vars)\nself.server_params = StdioServerParameters(command=cmd, args=arguments)\n\n# sink\nprocess = await anyio.open_process([command, *args])\n\n```\n\nFixed in commit `47bff65413beaa3c21bf633c1fae4e684348368c` (v4.5.69) by introducing a command allowlist:\n```python\nALLOWED_COMMANDS = {\"npx\", \"uvx\", \"node\", \"python\"}\nif cmd not in ALLOWED_COMMANDS:\n    raise ValueError(f\"Disallowed command: {cmd}\")\n```\n\n### PoC\n```python\n# tested on: praisonai==4.5.48\n# install: pip install praisonai==4.5.48\n# run: praisonai --mcp \"bash -c 'id \u003e /tmp/pwned'\"\n# verify: cat /tmp/pwned\n# expected output: uid=1000(...) gid=1000(...) groups=1000(...)\n```\n\n### Impact\n\nAny deployment where the `--mcp` argument is influenced by untrusted input is exposed to full OS command execution as the process user. No authentication is required.","status":"published","published":"2026-04-01T23:20:00Z","modified":"2026-04-06T22:54:00Z","cvss":[{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical"}],"cwes":["CWE-78"],"updated_at":"2026-11-02T14:39:48.966685Z"}],"nvd":[{"id":"CVE-2026-34935","description":"PraisonAI is a multi-agent teams system. From version 4.5.15 to before version 4.5.69, the --mcp CLI argument is passed directly to shlex.split() and forwarded through the call chain to anyio.open_process() with no validation, allowlist check, or sanitization at any hop, allowing arbitrary OS command execution as the process user. This issue has been patched in version 4.5.69.","status":"published","published":"2026-04-03T23:17:05.693Z","modified":"2026-07-24T22:10:00.14Z","cvss":[{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical","assessor":"secondary"}],"cwes":["CWE-78"],"updated_at":"2026-11-02T14:12:13.1424Z"}],"osv":[{"id":"CVE-2026-34935","title":"PraisonAI: OS Command Injection in MCPHandler.parse_mcp_command()","description":"PraisonAI is a multi-agent teams system. From version 4.5.15 to before version 4.5.69, the --mcp CLI argument is passed directly to shlex.split() and forwarded through the call chain to anyio.open_process() with no validation, allowlist check, or sanitization at any hop, allowing arbitrary OS command execution as the process user. This issue has been patched in version 4.5.69.","status":"published","published":"2026-04-03T22:48:21.261Z","modified":"2026-10-28T02:30:20.649634463Z","cvss":[{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical"}],"cwes":["CWE-78"],"updated_at":"2026-11-02T15:45:02.673625Z"},{"id":"GHSA-9gm9-c8mq-vq7m","title":"PraisonAI: OS Command Injection in MCPHandler.parse_mcp_command()","description":"### Summary\n\nThe `--mcp` CLI argument is passed directly to `shlex.split()` and forwarded through the call chain to `anyio.open_process()` with no validation, allowlist check, or sanitization at any hop, allowing arbitrary OS command execution as the process user.\n\n### Details\n\n`cli/features/mcp.py:61` (source) -\u003e `praisonaiagents/mcp/mcp.py:345` (hop) -\u003e `mcp/client/stdio/__init__.py:253` (sink)\n```python\n# source\nparts = shlex.split(command)\n\n# hop\ncmd, args, env = self.parse_mcp_command(command, env_vars)\nself.server_params = StdioServerParameters(command=cmd, args=arguments)\n\n# sink\nprocess = await anyio.open_process([command, *args])\n\n```\n\nFixed in commit `47bff65413beaa3c21bf633c1fae4e684348368c` (v4.5.69) by introducing a command allowlist:\n```python\nALLOWED_COMMANDS = {\"npx\", \"uvx\", \"node\", \"python\"}\nif cmd not in ALLOWED_COMMANDS:\n    raise ValueError(f\"Disallowed command: {cmd}\")\n```\n\n### PoC\n```python\n# tested on: praisonai==4.5.48\n# install: pip install praisonai==4.5.48\n# run: praisonai --mcp \"bash -c 'id \u003e /tmp/pwned'\"\n# verify: cat /tmp/pwned\n# expected output: uid=1000(...) gid=1000(...) groups=1000(...)\n```\n\n### Impact\n\nAny deployment where the `--mcp` argument is influenced by untrusted input is exposed to full OS command execution as the process user. No authentication is required.","status":"published","published":"2026-04-01T23:20:00Z","modified":"2026-06-29T12:26:49.148279892Z","cvss":[{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical"}],"cwes":["CWE-78"],"updated_at":"2026-11-02T15:46:43.875515Z"},{"id":"PYSEC-2026-471","title":"PraisonAI: OS Command Injection in MCPHandler.parse_mcp_command()","description":"### Summary\n\nThe `--mcp` CLI argument is passed directly to `shlex.split()` and forwarded through the call chain to `anyio.open_process()` with no validation, allowlist check, or sanitization at any hop, allowing arbitrary OS command execution as the process user.\n\n### Details\n\n`cli/features/mcp.py:61` (source) -\u003e `praisonaiagents/mcp/mcp.py:345` (hop) -\u003e `mcp/client/stdio/__init__.py:253` (sink)\n```python\n# source\nparts = shlex.split(command)\n\n# hop\ncmd, args, env = self.parse_mcp_command(command, env_vars)\nself.server_params = StdioServerParameters(command=cmd, args=arguments)\n \n# sink\nprocess = await anyio.open_process([command, *args])\n\n```\n\nFixed in commit `47bff65413beaa3c21bf633c1fae4e684348368c` (v4.5.69) by introducing a command allowlist:\n```python\nALLOWED_COMMANDS = {\"npx\", \"uvx\", \"node\", \"python\"}\nif cmd not in ALLOWED_COMMANDS:\n    raise ValueError(f\"Disallowed command: {cmd}\")\n```\n\n### PoC\n```python\n# tested on: praisonai==4.5.48\n# install: pip install praisonai==4.5.48\n# run: praisonai --mcp \"bash -c 'id \u003e /tmp/pwned'\"\n# verify: cat /tmp/pwned\n# expected output: uid=1000(...) gid=1000(...) groups=1000(...)\n ```\n\n### Impact\n\nAny deployment where the `--mcp` argument is influenced by untrusted input is exposed to full OS command execution as the process user. No authentication is required.","status":"published","published":"2026-06-29T11:50:46.601872Z","modified":"2026-07-13T16:15:32.236488212Z","cvss":[{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical"}],"updated_at":"2026-11-02T15:52:57.671918Z"}]}}
