Insecure DLL loading in Natural Language Toolkit - #VU159483
Published: November 5, 2026
Vulnerability details
The vulnerability allows a local, unprivileged attacker on a POSIX host to execute arbitrary code as a victim using Natural Language Toolkit (NLTK). Execution occurs when the victim renders a DependencyGraph, including automatic notebook display through _repr_svg_, or calls nltk.parse.dependencygraph.dot2img directly. This provides a local privilege-escalation and lateral-movement primitive through execution in the victim's account. No control over NLTK inputs is required.
The vulnerability exists due to dot2img resolving the Graphviz dot executable by bare name with find_binary and executing the resulting absolute path through subprocess.run without using nltk.pathsec.spawn_trusted. A local, unprivileged attacker can plant a malicious dot executable in a group- or world-writable directory on the victim's PATH, provided that executable is selected before a legitimate installation, or replace an existing dot in such a directory. The lookup rejects relative current-working-directory matches but accepts absolute matches from writable search-path directories. The subsequent execution omits checks that the executable and its parent directories cannot be replaced by another unprivileged user.
Both the text-format and binary-format execution branches in nltk/parse/dependencygraph.py have the same gap; this is not limited to a particular output format or dependent on resolving dot from the current working directory. The subprocess also inherits the environment without the loader and interpreter environment scrubbing normally provided by spawn_trusted. Consequently, variables such as LD_PRELOAD, DYLD_*, and GCONV_PATH reach the child process, creating an additional code-execution surface when an attacker can influence that environment.