Apr 7, 2026·5 min read·56 visits
Lupa <= 2.6 fails to enforce attribute_filter on Python built-ins like getattr(). Attackers can exploit this to access __class__ and __mro__, resulting in a sandbox escape and RCE. Update to Lupa 2.7+ or disable register_builtins.
CVE-2026-34444 is a critical sandbox escape vulnerability in the Lupa Python library, allowing remote code execution. The flaw arises from an incomplete attribute_filter implementation that fails to hook Python built-in functions like getattr and setattr, enabling attackers to bypass restrictions and access sensitive internal attributes.
Lupa integrates Lua and LuaJIT2 runtimes into CPython environments. It provides a mechanism to execute Lua code within a sandboxed environment while allowing controlled interaction with Python objects. The attribute_filter callback enforces access controls on Python attributes accessed from the Lua runtime.
CVE-2026-34444 represents an access control bypass vulnerability within this interaction layer. The attribute_filter successfully prevents direct attribute access from Lua syntax. However, the enforcement mechanism is incomplete and fails to govern access facilitated through Python built-in functions.
Attackers leverage this bypass to traverse the Python object hierarchy. By accessing restricted attributes such as __class__ and __mro__, adversaries achieve a complete sandbox escape resulting in arbitrary code execution within the host Python process.
The attribute_filter function serves as a security boundary between the Lua runtime and the host Python environment. When Lua code attempts to access a Python object attribute using standard syntax, Lupa intercepts the request. The wrapper object evaluates the requested attribute against the defined filter before granting access.
The vulnerability exists because this interception logic only hooks direct attribute access originating from the Lua interpreter. Python built-in functions, specifically getattr() and setattr(), operate directly on the underlying CPython objects. When these built-ins are exposed to the Lua environment, they execute without passing through Lupa's attribute filter wrapper.
If a developer initializes the LuaRuntime with Python built-ins enabled, an attacker can invoke getattr() from within the Lua script. Because getattr is a native CPython function, it retrieves the requested attribute natively, bypassing the custom wrapper and the associated security filter entirely.
During standard operation, a Lua script accessing an object attribute interacts with a proxy layer. Lupa wraps Python objects passed into the Lua environment. The wrapper's attribute accessor invokes the developer-defined attribute_filter callback. If the callback denies access, the wrapper raises an AttributeError.
When python.builtins is registered, the Lua environment gains a direct reference to the native CPython getattr function. The Lua script executes getattr(target_object, "__class__"). This execution path circumvents the Lupa proxy layer entirely.
The patch for CVE-2026-34444 introduces enforcement of the attribute_filter across all access methods. The structural fix requires Lupa to intercept calls to built-in functions or replace the exposed built-ins with wrapped equivalents that respect the established runtime filters.
Exploitation requires the Lua environment to possess access to Python built-in functions. This typically occurs when register_builtins=True is passed to the LuaRuntime constructor or when specific built-ins are manually injected into the global namespace. Once this prerequisite is met, the attacker executes a standard Python sandbox escape sequence.
The attacker retrieves the getattr function and applies it to any accessible Python object. This grants access to the object's __class__ attribute. The attacker then traverses the Method Resolution Order (MRO) via __mro__ to locate the base object class.
From the base object class, the attacker invokes __subclasses__() to enumerate all classes currently loaded in the CPython interpreter. The exploit payload iterates through this list to identify classes referencing sensitive modules, such as os._wrap_close. By accessing the __globals__ dictionary of the initialization method, the attacker retrieves the system function and executes arbitrary operating system commands.
local py = python.builtins
local getattr = py.getattr
local cls = getattr(user, "__class__")
local _, obj_cls = getattr(cls, "__mro__")
local subs = getattr(obj_cls, "__subclasses__")()Successful exploitation yields arbitrary code execution within the context of the host Python process. The attacker inherits the privileges of the application executing the Lupa runtime. This enables unauthorized read and write access to the underlying filesystem, interaction with network resources, and potential lateral movement within the infrastructure.
The vulnerability carries a CVSS 4.0 base score of 7.9 (High). The attack vector is Network (AV:N), assuming the application accepts user-supplied Lua scripts remotely. Attack complexity is Low (AC:L), and no special privileges (PR:N) or user interaction (UI:N) are required.
The EPSS score stands at 0.00068 (20.77th percentile), indicating a relatively low probability of widespread, indiscriminate exploitation. However, targeted attacks against systems executing untrusted Lua scripts remain highly viable. The vulnerability is not currently listed in the CISA Known Exploited Vulnerabilities (KEV) catalog.
System administrators and developers must upgrade the lupa package to version 2.7 or later. The updated release correctly applies the attribute_filter to object accesses mediated by Python built-in functions. This structural change eliminates the bypass vector and restores the integrity of the sandbox.
Organizations unable to deploy the update immediately must implement configuration changes to the LuaRuntime initialization. Administrators must ensure that register_builtins is set to False. This is the default behavior, but explicit verification is required for all instantiations.
# Secure configuration
lua = LuaRuntime(register_builtins=False, attribute_filter=protected_attribute_filter)If the application architecture necessitates exposing specific Python functions to the Lua runtime, developers must adopt an explicit allowlist approach. Rather than registering the entire python.builtins module, only specific, non-sensitive functions should be injected into the Lua global namespace.
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:H/SI:H/SA:H| Product | Affected Versions | Fixed Version |
|---|---|---|
lupa scoder | <= 2.6 | 2.7 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-284, CWE-639 |
| Attack Vector | Network |
| CVSS 4.0 | 7.9 (High) |
| EPSS Score | 0.00068 (20.77%) |
| Impact | Remote Code Execution (RCE) |
| Exploit Status | PoC Available |
| CISA KEV | Not Listed |
Improper Access Control and Authorization Bypass Through User-Controlled Key
A security inspection bypass vulnerability exists in the printenv utility of uutils coreutils (a Rust-based implementation of GNU coreutils) prior to version 0.6.0. Due to a semantic mismatch between POSIX environment variable specifications and Rust's strict UTF-8 validation rules, environment variables containing invalid UTF-8 byte sequences are silently omitted from printenv outputs. This allows local attackers to load and execute adversarial environment variables while remaining undetected by system administrators and automated security auditing tools.
An improper authorization vulnerability in Craft CMS allows authenticated Control Panel users to bypass volume view permissions and access signed fallback transform preview links for private assets via the assets/preview-thumb action.
CVE-2026-35371 is a logical validation vulnerability (CWE-451) in the Rust-based GNU coreutils clone (uutils/coreutils). When formatting pretty-print statistics for a process where the real User ID (UID) and effective User ID (EUID) differ, the id utility mistakenly uses the effective Group ID (EGID) to retrieve the effective user name. This mismatch can mislead administrative scripts or system administrators who rely on the command's stdout to verify privilege states.
CVE-2026-35339 is a logic vulnerability in the Rust-written `uutils/coreutils` implementation of the `chmod` utility. When executing recursively (`-R` or `--recursive`) over multiple target paths, the utility fails to accumulate the overall exit status, overwriting error codes from early failures with the status of the final target. This results in false-success exit codes (0), potentially leading security automation and deployment scripts to assume permission modifications succeeded when they actually failed.
A path validation bypass vulnerability exists in the chmod utility of uutils/coreutils before version 0.6.0. The '--preserve-root' safety mechanism relies on a literal string comparison, allowing local users to bypass root directory protection via unnormalized paths (such as '/../' or symbolic links) and recursively alter system-wide permissions.
An improper access control and mass assignment vulnerability in Scriban allows templates to write to arbitrary, restricted CLR properties (including private, internal, and init-only properties) of context-bound objects, causing unexpected state mutations on the host application heap.