PraisonAI Python Sandbox Escape via Code Injection
PraisonAI's AST-based Python sandbox is vulnerable to code injection allowing arbitrary code execution when running untrusted agent code by bypassing attribute filtering using `type.__getattribute__` which could lead to complete system compromise.
CVE search metadata
CVE search record: CVE-2026-40158. Severity: high. CVSS: 8.6. KEV: no. Brief: PraisonAI Python Sandbox Escape via Code Injection. Brief link: https://feed.craftedsignal.io/briefs/2024-01-17-praisonai-rce/
Triage facts
Revision 2- Evidence
- Unknown
- Severity
- High
- Sources
- 1 public source
- Freshness
- Revision 2Jan 17, 12:00 UTC
- Detection
- 2 rules
- Vulnerabilities
- 1 CVE
Revision history 1 entry · Revision 2
- Revision 2
Repaired a legacy canonical identity collision
Changed: slug
PraisonAI, a platform that executes untrusted agent code, contains a flaw in its AST-based Python sandbox. The sandbox attempts to restrict access to dangerous Python attributes like __subclasses__ and __globals__ by filtering ast.Attribute nodes. However, this filtering is incomplete, as it does not account for dynamic attribute resolution using built-in methods such as type.__getattribute__. An attacker can leverage this oversight to bypass the intended security restrictions and achieve arbitrary code execution. This vulnerability affects PraisonAI versions prior to 4.5.128 and was reported by Lakshmikanthan K (letchupkt). Successful exploitation allows attackers to escape the sandbox, enabling sensitive data access, arbitrary command execution, and potential system compromise.
Attack Chain
- The attacker injects malicious Python code into the PraisonAI agent execution environment.
- The injected code uses
type.__getattribute__to access the__bases__attribute of an integer class (int_cls). This bypasses the AST-based filter, which only checksast.Attributenodes. - The code retrieves the object class (
obj_cls) from the__bases__attribute. - The attacker then uses
type.__getattribute__again to access the__subclasses__attribute of theobj_cls. This further bypasses the filter. - The code iterates through all subclasses to find the
_wrap_closeclass. - It then uses
type.__getattribute__to get the__init__method of the_wrap_closeclass and subsequently accesses its__globals__attribute. - This provides access to the global namespace, allowing the attacker to retrieve the
systemfunction. - Finally, the attacker uses the
systemfunction to execute arbitrary commands, such as exfiltrating environment variables to an attacker-controlled server usingcurl.
Impact
This vulnerability allows attackers to escape the intended Python sandbox and execute arbitrary code with the privileges of the host process. Attackers can access sensitive data such as environment variables, API keys, and local files. Arbitrary system commands can be executed, potentially leading to modification or deletion of files. In environments that execute untrusted code, this can lead to full system compromise, data exfiltration, and potential lateral movement within the infrastructure. This poses a significant risk to multi-tenant agent platforms, CI/CD pipelines, and shared systems.
Recommendation
- Upgrade PraisonAI to version 4.5.128 or later to patch CVE-2026-40158.
- Deploy the Sigma rules in this brief to your SIEM to detect potential exploitation attempts.
- Review and harden any custom code that executes untrusted Python, paying special attention to dynamic attribute access patterns.
Detection coverage 2
Detect PraisonAI Sandbox Escape Attempt via type.__getattribute__
highDetects attempts to bypass PraisonAI's AST-based Python sandbox by using type.__getattribute__ to access restricted attributes like __subclasses__ or __globals__.
Detect PraisonAI Sandbox Escape Attempt via system call after attribute bypass
criticalDetects attempts to execute system commands after a potential sandbox escape, indicated by the use of type.__getattribute__ followed by a system call (e.g., curl, wget).
Detection queries are available on the platform. Get full rules →