CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-12243

CVE-2026-12243: Incomplete Path Traversal Validation and Percent-Encoding Bypass in NLTK

Amit Schendel
Amit Schendel
Senior Security Researcher

Aug 13, 2026·8 min read·19 visits

Executive Summary (TL;DR)

A path traversal vulnerability in NLTK 3.9.4 allows remote unauthenticated attackers to read arbitrary files via percent-encoded path traversal sequences because lexical validation occurs before URL decoding.

CVE-2026-12243 is a path traversal vulnerability in the Natural Language Toolkit (NLTK) version 3.9.4. The flaw exists because the input validation routine fails to account for percent-encoded directory traversal sequences like '..%2f' before passing them to urllib.request.url2pathname(), which decodes them into active traversal sequences.

Vulnerability Overview

The Natural Language Toolkit (NLTK) is an open-source Python platform for natural language processing. It is widely used in server-side pipelines, academic research, and machine learning workflows to tokenise, parse, and process text. Among its core features is the ability to load external and internal datasets, corpora, and resource packages dynamically via helper utilities.

CVE-2026-12243 describes a high-severity path traversal vulnerability in NLTK version 3.9.4. This vulnerability resides in the data resource loading modules, specifically within functions like nltk.data.load() and nltk.data.find(). The flaw arises from an order-of-operations conflict where lexical security validation is executed before URL decoding.

Attackers with control over input parameters passed to these functions can construct payloads that bypass directory sandbox constraints. The vulnerability is classified under CWE-22 (Improper Limitation of a Pathname to a Restricted Directory / 'Path Traversal'). This allows unauthenticated users to read arbitrary files accessible to the application's runtime context.

The following diagram illustrates the flow of a malicious payload through the vulnerable parsing chain:

Root Cause Analysis

The root cause of CVE-2026-12243 lies in NLTK's sequence of input processing operations. To prevent path traversal, NLTK version 3.9.4 implemented a regular expression validation check using the pattern _UNSAFE_NO_PROTOCOL_RE in nltk/data.py. This regex scans incoming resource locator strings for the literal character sequence ../, absolute directory markers, and Windows drive roots.

While this regex intercepts direct traversal sequences, it does not evaluate equivalent percent-encoded directory patterns. If an input string containing percent-encoded sequences such as ..%2f is provided, the regex validator verifies the characters literally. Because the literal pattern ../ is absent from the raw string, the input successfully passes the initial lexical safety checkpoint.

Following validation, the application maps the input string to a local filesystem location. To achieve this, NLTK executes urllib.request.url2pathname(). This method performs standard URL decoding, converting hexadecimal sequences back to their ASCII character representations. The validation-cleared string ..%2f is translated into the directory separator ../ only after the safety verification mechanism has terminated.

Consequently, NLTK constructs and opens an active path traversal sequence on the target filesystem. Because there are no secondary canonicalisation or boundary validation checks after the decoding step, the application processes the decoded path. The file access occurs within the operational environment of the running Python process, permitting unauthorized reading of files outside the designated resource boundaries.

Code Analysis & Patch Walkthrough

In the vulnerable implementation of NLTK 3.9.4, resource resolution relied on the direct parsing of input without post-decoding validation. This structure is visible in nltk/data.py where URL schemas are evaluated first and the local path resolution is performed via url2pathname() directly before loading. A patch was introduced in commit aec4fce1b84ad725b8975f7365b23a4f626572a9 (PR #3522) to address this systemic architectural flaw.

The patch introduces nltk/pathsec.py as a centralized I/O security module that performs absolute and relative sandboxing checks. This security layer verifies that any resolved filesystem access remains strictly bounded inside approved data paths. The validation routine converts both the input targets and the permitted root locations into resolved Path objects, evaluating their relationships after all decoding has completed.

Let us review the key parts of the security sentinel implemented in nltk/pathsec.py:

# Centrally handles path validation and prevents traversal escapes.
def validate_path(path_input, context="NLTK", required_root=None):
    if isinstance(path_input, int) or not path_input or not str(path_input).strip():
        return
    try:
        raw = path_input.path if hasattr(path_input, "path") else str(path_input)
 
        if "://" in raw:
            parsed = urlparse(raw)
            if parsed.scheme in ("http", "https", "ftp"):
                return
            if parsed.scheme == "file":
                raw = unquote(parsed.path)
 
        # Resolve paths strictly to evaluate absolute references and symlinks
        try:
            target = Path(raw).resolve()
        except (OSError, ValueError):
            lower_raw = raw.lower()
            if ".zip" in lower_raw:
                zip_idx = lower_raw.find(".zip") + 4
                target = Path(raw[:zip_idx]).resolve()
            else:
                target = Path(raw)
 
        # LAYER 1: Scoped Sandbox Check
        if required_root:
            root_raw = required_root.path if hasattr(required_root, "path") else str(required_root)
            scoped_root = Path(root_raw).resolve()
            # Verify the path is within the required root directory
            if not (target == scoped_root or target.is_relative_to(scoped_root)):
                raise ValueError(f"Security Violation [{context}]: Path {target} escapes root {scoped_root}")
 
        # LAYER 2: Global NLTK_DATA Sandbox Check
        allowed_roots = _get_allowed_roots()
        if any(target == root or target.is_relative_to(root) for root in allowed_roots):
            return
 
        # CWD Fallback (Requires explicit opt-in if ENFORCE is enabled)
        try:
            cwd = Path(os.getcwd()).resolve()
            if target == cwd or target.is_relative_to(cwd):
                if any(cwd == root for root in allowed_roots):
                    return
                msg = "Security Violation: CWD access restricted in ENFORCE mode."
                if ENFORCE:
                    raise PermissionError(msg)
                else:
                    warnings.warn(f"Security Warning [{context}]: Path {target} allowed via CWD.", RuntimeWarning, stacklevel=3)
                    return
        except (OSError, ValueError):
            pass
 
        msg = f"Security Violation [{context}]: Unauthorized path {target}"
        if ENFORCE:
            raise PermissionError(msg)
        else:
            warnings.warn(msg, RuntimeWarning, stacklevel=3)
    except (PermissionError, ValueError):
        raise

The core loader integration inside nltk/data.py was altered to force decoded local paths through the path validation routines. By executing _secure_open and validating paths early in the call stack of _open(), the framework intercepts malicious traversal vectors before they are handled by underlying low-level system calls.

Exploitation & Attack Scenarios

Exploitation of CVE-2026-12243 requires that an attacker have influence over the string parameter supplied to NLTK resource loading functions. This condition is common in NLP applications exposing web search interfaces, translation engines, or model-selection dropdowns. If the input is not pre-validated at the application layer, the parameter passes directly to the NLTK backend.

An attacker targeting a Linux environment can construct a path traversal payload containing percent-encoded sequences to read sensitive configurations. By submitting ..%2f..%2f..%2f..%2f..%2fetc/passwd, the request bypasses NLTK's regex, undergoes URL decoding to ../../../../../etc/passwd, and is resolved relative to the data search paths. The application then performs a file read operation, returning the file content to the response body.

This technique extends to retrieving runtime environmental variables and cloud credentials from internal endpoints. On containerized or cloud-hosted instances, sending ..%2f..%2f..%2f..%2f..%2fproc/self/environ retrieves active session tokens, database passwords, and API keys. Similarly, Windows targets are vulnerable to the retrieval of system parameters through payloads targeting directories such as ..%2f..%2f..%2f..%2f..%2fWindows/System32/drivers/etc/hosts.

Impact Assessment

The security impact of CVE-2026-12243 is classified as High, achieving a CVSS v3.0 Base Score of 7.5. The vulnerability affects the confidentiality of the system directly, allowing unauthenticated remote read access to files accessible to the application process. It does not provide immediate integrity or availability impacts, as the traversal mechanism is restricted to read operations.

The attack vector is network-based, requires no privileges, and demands no user interaction. Because NLTK is frequently deployed in API routing layers and multi-tenant pipelines, exploitation can lead to a compromise of adjacent application databases or cloud infrastructure if sensitive keys are recovered from local configuration files. This structural risk is amplified in microservice architectures where services run with elevated system permissions.

While EPSS data shows a low exploitation probability of 0.58% within thirty days, the presence of documented proof-of-concept indicators raises the likelihood of targeted exploitation. Organizations operating multi-tenant natural language systems must treat this as a critical exposure, particularly since upgrading NLTK without explicitly modifying configuration settings does not fully mitigate the risk.

Remediation & Detection Guidance

Remediation of this vulnerability requires upgrading NLTK to version 3.9.5 or higher, where the centralized pathsec security framework is fully integrated. However, installing the patch is insufficient on its own due to the backward-compatibility architecture. By default, NLTK sets the validation mode parameter nltk.pathsec.ENFORCE to False, which limits the system to emitting warnings instead of blocking file read operations.

To achieve complete remediation, software developers must explicitly enable strict security enforcement within their codebase. This is accomplished by setting the enforcement toggle to True at the application entry point. This modification ensures that any unauthorized path traversal, SSRF, or Zip-slip attempt results in an immediate exception, stopping the file execution pipeline.

The following Python code illustrates the correct configuration sequence to secure NLTK resource loading operations:

import nltk
import nltk.pathsec
 
# Enable strict enforcement to block path traversal attempts
nltk.pathsec.ENFORCE = True
 
# If your application must access local resources in the working directory:
nltk.data.path.append('.') # Explicitly authorize current directory access

Security teams can monitor log files for specific path violation signatures to detect exploitation attempts. When NLTK runs in the default warn-only configuration, path traversal bypass attempts will generate a RuntimeWarning containing strings like Security Warning [pathsec.open]: Path or Security Violation. Configuring alert monitors to trigger on these specific string patterns allows teams to identify probing activities before enabling enforcement.

Technical Appendix

CVSS Score
7.5/ 10
CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

Affected Systems

Applications employing NLTK for dynamic resource/corpora loadingWeb-based natural language processing pipelines using NLTK 3.9.4Jupyter notebooks and machine learning environments loading external corpus names

Affected Versions Detail

Product
Affected Versions
Fixed Version
NLTK (Natural Language Toolkit)
NLTK Project
3.9.43.9.5
AttributeDetail
CWE IDCWE-22
Attack VectorNetwork (AV:N)
CVSS Base Score7.5
EPSS Score0.00583 (Percentile: 44.89%)
ImpactArbitrary File Read / Information Disclosure
Exploit StatusProof-of-Concept (PoC) documented
KEV StatusNot listed
CWE-22
Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

Vulnerability Timeline

Commit aec4fce1b84ad725b8975f7365b23a4f626572a9 merged into NLTK master branch
2026-03-22
CVE-2026-12243 published by CVE Numbering Authority @huntr_ai
2026-06-30
CVE-2026-12243 record added to the National Vulnerability Database (NVD)
2026-06-30

References & Sources

  • [1]Official CVE Record
  • [2]NVD Advisory Entry
  • [3]NLTK Repository Security Commit
  • [4]NLTK Security Patch Pull Request
  • [5]Huntr Bug Bounty Database Entry
  • [6]Wiz Vulnerability Analysis Portal

More Reports

•1 day ago•CVE-2026-11748
6.9

CVE-2026-11748: Unauthenticated LDAP Injection in Central Dogma Server Authentication

An LDAP injection vulnerability exists in the centraldogma-server-auth-shiro module of LY Corporation Central Dogma before version 0.84.0. The search logic dynamically constructs LDAP search filters by interpolating user-provided usernames without escaping RFC 4515 metacharacters. Unauthenticated remote attackers can leverage this flaw to bypass authentication, enumerate directory hierarchies, and access unauthorized resources.

Alon Barad
Alon Barad
9 views•6 min read
•1 day ago•CVE-2026-11746
9.4

CVE-2026-11746: Use of Hard-coded ZooKeeper Replication Secret 'ch4n63m3' in Central Dogma Server

CVE-2026-11746 is a critical vulnerability in Central Dogma Server prior to version 0.84.0, where an embedded ZooKeeper replication secret silently falls back to a publicly known, hard-coded default string ('ch4n63m3'). Remote attackers with access to the replication network can authenticate as legitimate cluster peers, potentially leading to unauthorized data exposure, state manipulation, or complete cluster takeover.

Amit Schendel
Amit Schendel
7 views•6 min read
•1 day ago•CVE-2026-56665
4.2

CVE-2026-56665: Logical Validation Bypass in ZITADEL External JWT Identity Provider

A logical verification flaw in ZITADEL's external JWT Identity Provider validation allows attackers to bypass session expiration checks. If an incoming JWT lacks the 'exp' claim, the system skips validation entirely, creating an indefinitely valid session. This issue has been addressed in versions 3.4.12 and 4.15.2.

Alon Barad
Alon Barad
7 views•7 min read
•1 day ago•CVE-2026-59149
6.5

CVE-2026-59149: Sibling Directory Path Traversal in Mockoon Backend Server

CVE-2026-59149 identifies a directory traversal vulnerability in `@mockoon/commons-server`, the backend mock-server library powering the Mockoon application. The flaw occurs in the path containment validation logic used during raw file response generation. An unauthenticated attacker can exploit this weakness to retrieve arbitrary files from sibling directories sharing a common prefix with the designated static base directory.

Amit Schendel
Amit Schendel
9 views•5 min read
•1 day ago•CVE-2026-59148
8.8

CVE-2026-59148: Unauthenticated Administrative API and CORS Misconfiguration in Mockoon

An in-depth analysis of CVE-2026-59148, a high-severity flaw in Mockoon where unauthenticated administrative endpoints and a wildcard Cross-Origin Resource Sharing (CORS) policy allow remote execution, state poisoning, and credential theft.

Alon Barad
Alon Barad
11 views•6 min read
•1 day ago•CVE-2026-56666
4.8

CVE-2026-56666: Account Takeover via Improper Email Verification in ZITADEL Federated Identity Handler

An improper authentication vulnerability (CWE-287) in ZITADEL's external identity provider handler before version 4.15.3 allows remote attackers to perform complete account takeover. When auto-linking by email is enabled, ZITADEL verifies that the local target account has a verified email address but fails to verify if the external provider confirmed ownership of that same email. Attackers can exploit this by registering an unverified account with a victim's email address on a permissive external provider, leading to unauthorized account binding and persistent access.

Amit Schendel
Amit Schendel
7 views•7 min read