CVE-2026-107716: Banks: Symlink traversal and arbitrary file disclosure/overwrite in DirectoryPromptRegistry
Summary In banks.registries.DirectoryPromptRegistry, prompt file paths and the index file (index.json) do not refuse symbolic links. When a prompt directory contains or accepts untrusted files (e.g. unpacked archives, shared repositories, or multi-tenant folders), symbolic links pointing outside the registry root can be used to disclose arbitrary files via scan() / get() or overwrite arbitrary files via set() / save().
Details Following PR #77, DirectoryPromptRegistry validates path resolution for prompt names. However: 1. self.indexpath (index.json) is not checked for symbolic links. A symlink pointing to an external target (e.g. a configuration file) will be overwritten by save() upon reg.set(), or read via load(). 2. In scan(), discovered .jinja files are opened and indexed without checking if path.issymlink() or if the resolved path escapes the registry root. A symlink pointing to a sensitive file outside the root is read and indexed. 3. In set(), promptfile.writetext(...) is called without checking if promptfile is an existing symbolic link pointing outside the root.
Impact Arbitrary file disclosure (CWE-59 / CWE-200) and arbitrary file overwrite (CWE-59) in applications where prompt directories can be influenced by untrusted users or extracted from archives.
Proof of Concept python import os from pathlib import Path from banks.registries.directory import DirectoryPromptRegistry, DEFAULTINDEXNAME from banks.prompt import Prompt
Disclose external file via symlink in prompt directory regdir = Path("/tmp/registry") regdir.mkdir(existok=True) secret = Path("/tmp/secret.txt") secret.writetext("SECRETAPITOKEN")
os.symlink(secret, regdir / "leak.0.jinja") reg = DirectoryPromptRegistry(regdir, forcereindex=True) print("Disclosed content:", reg.get(name="leak", version="0").raw)
Overwrite external file via symlink index target = Path("/tmp/target.conf") target.writetext("ORIGINAL") (regdir / DEFAULTINDEXNAME).unlink(missingok=True) os.symlink(target, regdir / DEFAULTINDEXNAME) reg.set(prompt=Prompt("pwn", name="test", version="1")) print("Target overwritten:", target.readtext())
Remediation 1. In validateindexpath(): verify indexpath is not a symlink and resolves within path. 2. In scan(): reject path.issymlink() and check path.resolve().isrelativeto(root). 3. In set(): reject existing symbolic links before writing.
A tested fix and regression tests have been prepared and pushed to: https://github.com/jankesec/banks/tree/fix-directory-registry-symlinks-and-nesting
Other sources
Banks generates meaningful LLM prompts using a simple template language. Prior to 2.5.1, Banks DirectoryPromptRegistry does not reject symbolic links for index.json or discovered and existing .jinja prompt files. In an application where untrusted users can influence a prompt directory, DirectoryPromptRegistry.scan() and DirectoryPromptRegistry.get() can follow a link outside the registry root and disclose a file, while DirectoryPromptRegistry.set(), DirectoryPromptRegistry.save(), and DirectoryPromptRegistry.load() can read or overwrite an external link target. The issue requires attacker influence over the registry directory or its extracted contents. This issue is fixed in version 2.5.1.
— MITRE
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
pip/banksto a version that resolves this vulnerability.Fixed in 2.5.1 - Upgrade
Upgrade
Banksto a version that resolves this vulnerability.Fixed in 2.5.1
Event History
Frequently Asked Questions
Which deployments are realistically exposed?
Deployments are exposed when untrusted users can influence a Banks prompt registry directory or its extracted contents. The affected component is DirectoryPromptRegistry in versions before 2.5.1.
What access does an attacker need to exploit this issue?
An attacker needs the ability to place or influence symbolic links in the registry directory or in content extracted into it. The issue involves symlinks named index.json and discovered or existing .jinja prompt files.
What can an attacker do through the vulnerable registry operations?
Scanning or retrieving prompts can follow a symlink outside the registry root and disclose the linked file. Setting, saving, or loading prompts can read or overwrite the external symlink target.
What is the available remediation?
Upgrade Banks to version 2.5.1, which fixes the issue. If an immediate upgrade is not possible, do not allow untrusted users to influence the prompt directory or its extracted contents.