Link following in Natural Language Toolkit - #VU159486
Published: November 5, 2026
Vulnerability details
The vulnerability allows an attacker with write access to a trusted NLTK data root to bypass the data-root sandbox and obtain query results from SQLite databases outside all registered roots. The exposed databases must be readable by the application process. If the caller supplies a write query, that query is also redirected to the outside database, and SQLite may create journal or write-ahead-log sidecar files beside it; these are plausible integrity effects, not a demonstrated arbitrary-write primitive.
The vulnerability exists due to nltk.sem.chat80.sql_query() passing the path returned by nltk.data.find(dbname) directly to sqlite3.connect() without validating its resolved location. Resource-name checks are lexical, while FileSystemPathPointer uses os.path.abspath and an existence check without resolving symbolic links. A remote attacker can exploit this behavior only if they also have write capability within a registered data root, allowing them to plant a symbolic link at the expected database resource location and have the application query that resource through sql_query() or sql_demo(). SQLite follows the link to the attacker-selected outside database even though the resource name itself passes the lexical checks.
The sandbox normally enforces containment through nltk.pathsec.open and validate_path, which resolve real paths and reject targets outside the allowed roots. FileSystemPathPointer.open() reaches this enforcement, but the direct SQLite connection bypasses it. An in-root link such as corpora/city_database/city.db can therefore be rejected by the pointer's sandboxed open operation while still yielding outside database rows through sql_query(). Non-SQLite targets raise sqlite3.DatabaseError rather than exposing arbitrary file contents. Exploitation requires the stated local filesystem write capability; network access is not inherently required.