- Severity: HIGH
- CVE: CVE-2026-61536
- Ecosystems: pip
- Packages: banks
## Summary
`banks` parses `Tool` JSON objects from the rendered body of `{% completion %}` blocks and later resolves their
`import_path` field through `importlib.import_module(…)` + `getattr(…)` to obtain the callable that handles a tool
call. There is no allowlist or sanitization on `import_path`, so any importable Python attribute (e.g. `os.system`,
`subprocess.getoutput`) can be selected. When the LLM emits a `tool_calls` entry whose `function.name` matches the
attacker-supplied tool name, the resolved callable is invoked with kwargs decoded from `tool_call.function.arguments`,
yielding arbitrary code execution in the banks-hosting process.
This is distinct from GHSA-gphh-9q3h-jgpp / CVE-2026-44209. That advisory was fixed in 2.4.2 by switching
`src/banks/env.py` from `Environment` to `SandboxedEnvironment`. The fix does not touch
`src/banks/extensions/completion.py`, and the unsafe import + getattr chain still executes on 2.4.2. The malicious
`Tool` JSON is plain text in the rendered template body — it requires no Jinja attribute access, so the sandbox is
irrelevant.
## Vulnerable Code
`src/banks/extensions/completion.py:79-98`
“`python
def _get_tool_callable(self, tools, tool_call):
for tool in tools:
if tool.function.name == tool_call.function.name:
module_name, func_name = tool.import_path.rsplit(“.”, maxsplit=1)
module = importlib.import_module(module_name)
return getattr(module, func_name)
src/banks/extensions/completion.py:128-129 (sink…
Source: GitHub Security Advisories · 2026-11-05