#3793·nltk

Security Tracking: NLTK Vulnerability Mitigation Roadmap

Author: ekafCreated Aug 28, 2026Updated Sep 2, 2026

This issue tracks the 20 remaining unfixed NLTK security advisories from Huntr.com, categorized by shared implementation logic and common code-fixing patterns to maximize code reuse and streamline pull request reviews.

These reports where filed near the end of June 2026, so the corresponding CVEs are scheduled for publication in the last week of September.

Cluster 1: Downloader & Archive Integrity (nltk/downloader.py)

Shared Code/Fix Logic: Input stream bounds checking, strict archive member path validation, and cryptographic signature verification replacing MD5.

Component / Vulnerability CVE / ID Status
nltk.downloader.Downloader (Zip-Slip / hard-link overwrite) Unknown PR #3804
nltk.downloader.Downloader (MD5 trust & colliding ZIP substitution) Unknown Pending PR
nltk/downloader.py (Unbounded response size / disk exhaustion) Unknown (CWE-400) Pending PR

Cluster 2: Data Loading & Deserialization (nltk/data.py)

Shared Code/Fix Logic: Resource loading safety checks, disabling insecure pickle over HTTP, and preventing arbitrary local module shadowing (json.py/yaml.py).

Component / Vulnerability CVE / ID Status
nltk.data.load() (ReDoS via local json.py / yaml.py import injection) CVE-2026-12914 PR #3798
nltk.data.load() (Insecure deserialization via pickle.load() on HTTP sources) CVE-2026-14937 PR #3794
nltk.data.path (Namespace traversal / stale cache entries) CVE-2026-14707 Addressed upstream / PR #3753

Cluster 3: Newline & Protocol Sanitization (nltk.tag & nltk.sem)

Shared Code/Fix Logic: A common input sanitization helper to strip or reject newline characters (\n, \r) from text inputs before they are written to line-oriented subprocess protocols or parser control records.

Component / Vulnerability CVE / ID Status
nltk.tag.hunpos.HunposTagger.tag() (Newline protocol poisoning) CVE-2026-14710 Pending PR
nltk.sem.boxer.Boxer (Newline sentence text META control-record injection) CVE-2026-14715 Pending PR
WORKDIR/runner.py / CoreNLPParser (Batch-boundary injection) CVE-2026-14728 Addressed upstream / PR #3788
WORK/runner.py / StanfordParser (Batch-boundary injection) Unknown (CWE-501) Addressed upstream / PR #3782 / #3788

Cluster 4: Corpus Readers (nltk.corpus.reader)

Shared Code/Fix Logic: XML parsing safety, tree builder sanitization, and state isolation in lazy iterators.

Component / Vulnerability CVE / ID Status
nltk.corpus.reader.mte.MTECorpusReader (Shared lazy tag state corruption) CVE-2026-14944 Fixed in PR #3792
nltk.corpus.reader.toolbox.ToolboxCorpusReader.xml() (XML/XSS marker injection) CVE-2026-14718 Fixed in PR #3800

Cluster 5: Isolated Individual Fixes (Unique Code Paths)

Modules requiring distinct, non-overlapping code changes:

Component / Vulnerability CVE / ID Status
nltk.parse.malt.MaltParser.parse_tagged_sents() (CoNLL row injection via unescaped tokens) CVE-2026-14720 Pending PR
nltk.decorators.new_wrapper() (Dynamic eval() signature metadata execution) CVE-2026-14727 Pending PR
nltk.twitter.twitterclient.TweetViewer (Terminal control sequence emission) CVE-2026-14724 Pending PR
nltk.tokenize.repp.ReppTokenizer.tokenize_sents() (Unbounded plaintext temporary files) Unknown (CWE-459) Pending PR
nltk.__version__ (config_java() / java()) (Concurrent JVM option injection) Unknown (CWE-567) Pending PR
nltk.tag.stanford.StanfordTagger.tag_sents() (Shared _input_file_path state exposure) CVE-2026-14712 Addressed upstream / PR #3781 / #3787
nltk.pathsec / corenlp.py (SSRF network reconnaissance) CVE-2026-14945 Addressed upstream / PR #3753 / #3787
nltk.inference.prover9.Prover9Parent.prover9_input() (Delimiter injection end_of_list) CVE-2026-14709 Pending PR