Mar 2, 2026·5 min read·128 visits
GNU `telnetd` fails to scrub environment variables when spawning `/bin/login` as root. This allows attackers to inject `CREDENTIALS_DIRECTORY` (bypassing authentication in `util-linux` 2.40+) or `GCONV_PATH` (loading malicious shared objects via `glibc`). The vulnerability leads to immediate root compromise.
A critical privilege escalation vulnerability exists in GNU Inetutils `telnetd` versions through 2.7. The daemon fails to properly sanitize the environment before executing the login process, allowing attackers to inject dangerous environment variables. Because `telnetd` executes `/bin/login` as root without triggering the kernel's `AT_SECURE` protection, these variables are preserved. This allows local attackers—and potentially remote attackers depending on configuration—to gain root privileges by manipulating `systemd` credentials or `glibc` character set conversion paths.
CVE-2026-28372 identifies a flaw in the environment sanitization logic of the GNU Inetutils telnetd daemon. The vulnerability arises from the interaction between the telnet daemon, the login binary, and the Linux kernel's handling of privileged process execution. Specifically, telnetd accepts environment variables from the client via the Telnet protocol (RFC 1572) and passes them to the /bin/login process.
Under normal circumstances, when a process transitions from a lower privilege level to a higher one (e.g., executing a SETUID binary), the Linux kernel sets the AT_SECURE auxiliary vector. This signals the dynamic linker (ld.so) and the C library (glibc) to scrub sensitive environment variables such as LD_PRELOAD, GCONV_PATH, and GLIBC_TUNABLES. This mechanism is a primary defense against environment injection attacks.
However, telnetd runs as root and executes /bin/login also as root. Because the User ID (UID) does not change during this execve call, the kernel does not set AT_SECURE. Consequently, login starts with a user-controlled environment in a non-secure mode. It becomes the sole responsibility of telnetd to sanitize this environment. The failure to filter variables like CREDENTIALS_DIRECTORY or GCONV_PATH allows attackers to influence the execution flow of the privileged login process.
The root cause is a logic error in telnetd regarding the assumption of security boundaries. The daemon relied on a blacklist approach (or insufficient filtering) to remove dangerous variables. Blacklisting is historically fragile; as new features are added to downstream components (like systemd integration in login or new glibc features), the list of dangerous variables expands, rendering previous blacklists obsolete.
Specifically, the regression relates to CVE-1999-0073, a 27-year-old vulnerability involving telnetd and LD_ variables. While LD_PRELOAD might have been filtered in intervening years, newer variables like CREDENTIALS_DIRECTORY (introduced in util-linux 2.40) were not anticipated. The lack of AT_SECURE means that glibc honors these variables just as it would for a normal user process.
When telnetd constructs the argument vector for login, it copies environment variables provided by the client. Without a strict whitelist (e.g., only allowing TERM, DISPLAY, USER), any variable not explicitly blocked is passed through. This passes control of critical configuration paths—such as where to load shared libraries or where to read authentication credentials—directly to the attacker.
The first major exploitation vector targets the CREDENTIALS_DIRECTORY environment variable, supported by util-linux versions 2.40 and later. This variable is part of the systemd service credentials specification. When login initializes, it checks this directory for credential files.
If an attacker can define CREDENTIALS_DIRECTORY, they can point it to a directory they control, such as /tmp/fake_cred. The login process will search this directory for a file named login.noauth. If this file exists and contains the string "yes", login is instructed to bypass password authentication entirely.
To exploit this, a local user creates the directory and file, then connects to the local telnetd instance. By using the Telnet ENVIRON option to export CREDENTIALS_DIRECTORY=/tmp/fake_cred, the attacker forces the spawned login process to read their malicious configuration. This results in an immediate root shell without a password.
The second vector exploits the GCONV_PATH variable used by glibc for character set conversion. This is a classic attack method effectively reintroduced because AT_SECURE is missing. The iconv_open() function in glibc uses GCONV_PATH to locate shared objects (.so files) that handle specific character encodings.
An attacker creates a malicious shared object and a gconv-modules configuration file in a writable directory. They then connect via Telnet and export three variables: GCONV_PATH (pointing to their directory), LANGUAGE (setting a locale that requires conversion), and OUTPUT_CHARSET (specifying the target charset).
When /bin/login runs, it attempts to localize its output (e.g., printing the "Login:" prompt). This triggers gettext, which calls iconv_open to convert the message to the requested charset. glibc sees the attacker's GCONV_PATH, loads the malicious shared object to handle the conversion, and executes the attacker's code with root privileges. This execution happens before authentication is even attempted.
The impact of CVE-2026-28372 is critical, resulting in Local Privilege Escalation (LPE) to root. While the vulnerability manifests in the telnetd daemon, the successful exploitation relies on the configuration of the system (presence of util-linux >= 2.40 for Vector 1) or standard glibc behavior (Vector 2).
Confidentiality: Complete loss. An attacker can read any file on the system, including /etc/shadow and database credentials.
Integrity: Complete loss. An attacker can modify system binaries, install persistence mechanisms, or alter logs.
Availability: Complete loss. An attacker can delete files, stop services, or reboot the system.
The requirement for telnetd to be running reduces the attack surface on modern systems, where SSH is the standard. However, legacy systems, embedded devices, and specific enterprise environments running GNU Inetutils are highly vulnerable. The exploit is reliable and requires no race conditions or complex memory corruption.
The primary remediation is to apply the official patch which shifts telnetd from a blacklist approach to a whitelist approach. The patched version explicitly unsets all environment variables except for a small set of known-safe variables (like TERM).
Patched Versions: Users must upgrade to GNU inetutils version 2.8 or apply the patch found in commit 3953943d8296310485f98963883a798545ab9a6c.
Operational Workarounds:
telnetd service immediately. Replace it with OpenSSH, which has a robust history of secure environment handling.localhost or trusted management IPs to prevent remote triggering of the vulnerability, although this does not prevent local users from exploiting it via loopback.telnetd or login from reading files in /tmp or loading arbitrary shared objects, effectively neutralizing the exploit vectors.CVSS:3.1/AV:L/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
inetutils GNU | <= 2.7 | 2.8 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-829 |
| Attack Vector | Local / Network (if allowed) |
| CVSS v3.1 | 7.4 (High) |
| EPSS Score | 0.01% (Low probability) |
| Impact | Privilege Escalation (Root) |
| Exploit Status | Proof of Concept Available |
Inclusion of Functionality from Untrusted Control Sphere
An uncontrolled resource consumption vulnerability exists in the Scala-based http4s-blaze-server package of the http4s/blaze library. The vulnerability allows remote, unauthenticated attackers to cause an Out of Memory Error (OOM) and JVM crash by streaming a continuous sequence of small or empty WebSocket continuation frames with the FIN bit set to 0. This bypasses typical payload size checks because of the JVM's per-object allocation overhead, leading to rapid heap exhaustion with minimal network bandwidth.
A critical path traversal vulnerability has been identified in the OpenList Go-based backend package. The vulnerability exists within the batch rename handler because the application does not validate the source filename parameter before constructing filesystems paths. This omission allows authenticated users to escape their designated directory and rename files in sibling paths.
OpenList version 4.2.3 and prior is vulnerable to an authorization bypass and metadata leakage. When configured with the Bleve search engine backend, OpenList fails to perform separator-aware path matching when validating tenant containment. This allows authenticated users to access sibling directories sharing similar name prefixes. Furthermore, the search backend returns unfiltered global result counts, leaking existence verification data of unauthorized files via side-channel analysis.
An authorization bypass vulnerability in OpenList version 4.2.3 and below allows authenticated users to read arbitrary files outside of their designated base directories due to an insecure path prefix check using Go's standard strings.HasPrefix function.
A security policy bypass vulnerability exists in the AWS API MCP Server (awslabs-aws-api-mcp-server) from version 0.2.13 through 1.3.46. When the server fails to load the read-only operations index during startup (due to transient network failures, file permission issues, or other exceptions), it logs a warning but continues running in an insecure, degraded state. Under this condition, the security policy engine fails open, silently skipping all subsequent security checks and consent prompts for the lifetime of the process. This permits unauthorized mutating AWS CLI commands to execute via indirect prompt injection attacks.
An incomplete escaping vulnerability in the npm package 'shescape' allows unauthenticated users to trigger dynamic shell expansions, absolute path disclosure, and command block break-outs on Unix and Windows systems.