Open-Source Security Intelligence

Know every vulnerability
before it knows you.

DevGuard continuously monitors your dependencies and alerts you when CVEs like this one affect your stack — with real-time threat intelligence built for developers.

Search

GHSA-6hwm-xvph-95vm

HighCVSS 7.8 / 10
Published Sep 1, 2026·Last modified Sep 1, 2026
Affected Components(1)
PyPI logonltk
< 3.10.3
Description

Two NLTK sites executed the Graphviz dot program by bare name, so process creation resolved it via the search path — and on Windows via the current working directory — rather than a validated absolute location. An attacker who can place a file named dot where resolution looks (the CWD on Windows, or a writable/relative entry such as . on PATH) has their binary executed in place of Graphviz (arbitrary code execution).

Affected (<= 3.10.2):

  • nltk.parse.dependencygraph.dot2img — called find_binary("dot") but discarded the returned validated path and then ran the bare name ["dot", ...], so the validation had no effect.
  • nltk.translate.api.AlignedSent._repr_svg_ — ran the bare name with no validation at all (IPython SVG rendering).

This is the same class already fixed for the senna, weka, boxer, malt, repp and hunpos wrappers. nltk.internals.find_binary refuses a CWD-relative match for a bare tool name and returns only a trusted absolute path; the fix runs that path in both sites.


Attack demonstration

Captured output, not illustrative. A ./dot that writes a PWNED marker, planted in the CWD with . prepended to PATH.

The vulnerable behaviour (old bare-name exec):

Control (OLD behavior) — bare ['dot'] in this dir with '.' on PATH:
  bare ['dot'] executed planted binary = True

The patched functions refuse it:

FIXED code, with ./dot planted and '.' on PATH:
  dependencygraph.dot2img : Exception "Cannot find the dot binary..."  | planted-binary-executed=False  safe
  AlignedSent._repr_svg_  : Exception "Cannot find the dot binary..."  | planted-binary-executed=False  safe

And find_binary itself was attacked directly (the fix trusts nothing else):

Attack 1: ./dot in CWD, no dot on PATH            -> LookupError (refused)  safe
Attack 2: ./dot/dot (dir 'dot' holding 'dot')     -> LookupError (refused)  safe
Attack 3: '.' on PATH + ./dot                     -> LookupError (refused)  safe
Attack 4: attacker-writable ABSOLUTE dir on PATH  -> returned /…/evilbin/dot (absolute)

Attack 4 is out of scope: trusting an absolute directory that is already on PATH is the operating system's own trust model — an attacker who can write to a PATH directory owns the account regardless of NLTK. find_binary defends specifically against the CWD/relative injection that bare-name exec is vulnerable to (attacks 1–3), which is exactly what this fix inherits.

Environment: python 3.13.7. dot is not required to reproduce — the planted binary is the payload.

Upload your SBOM

Upload your own SBOM in CycloneDX 1.6 or higher (JSON) directly here to check your vulnerabilities.

Risk Scores
Base Score
7.8

The vulnerability requires local access to the device to be exploited. It is easy for an attacker to exploit this vulnerability. An attacker needs basic access or low-level privileges. No user interaction is needed for the attacker to exploit this vulnerability. The impact is confined to the system where the vulnerability exists. There is a high impact on the confidentiality of the information. There is a high impact on the integrity of the data. There is a high impact on the availability of the system.

Threat Intelligence
7.1

Exploitation activity has been observed. Apply available patches or mitigations urgently.

EPSS
0.12%

The exploit probability is very low. The vulnerability is unlikely to be exploited in the next 30 days.

Exploit
Not available

We did not find any exploit available. Neither in GitHub repositories nor in the Exploit-Database.

Browse More

Scan your project

Continuously monitor your dependencies and get alerted when vulnerabilities like this one affect your stack.

Checkout DevGuard