Severity by source
AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N
Local vector and low-privilege requirement reflect mandatory local account and environment manipulation before setuid execution; C:H/I:H capture full auth bypass enabling root access via sudo.
Primary rating from Vendor (GitHub_M).
CVSS VectorVendor: GitHub_M
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N
Lifecycle Timeline
4DescriptionCVE.org
pam_usb provides hardware authentication for Linux using removable media. In versions prior to 0.9.2, getenv() environment variables XRDP_SESSION, DISPLAY and TMUX allow environment variable injection into local-check logic. These environment variables influence whether a current session is local or remote, and a PAM module that runs in the context of setuid binaries (sudo, su), getenv() returns attacker-controlled values whenever the process environment has been manipulated by a local user. This issue has been fixed in version 0.9.2.
AnalysisAI
Environment variable injection in pam_usb prior to version 0.9.2 allows a local authenticated user to bypass hardware USB token authentication by manipulating the XRDP_SESSION, DISPLAY, or TMUX environment variables before invoking setuid binaries such as sudo or su. Because the PAM module calls standard getenv() - which does not sanitize values in privileged contexts - attacker-controlled environment data is used to determine whether the current session is local or remote, potentially defeating the core purpose of hardware-enforced authentication. No public exploit has been identified at time of analysis and the vulnerability is not listed in CISA KEV, though the authentication bypass impact makes this a high-priority upgrade for any deployment relying on pam_usb for privileged command gating.
Technical ContextAI
pam_usb is a Linux Pluggable Authentication Module (PAM) that enforces hardware-based authentication using removable USB media, identified by CPE cpe:2.3:a:mcdope:pam_usb:*:*:*:*:*:*:*:*. The root cause is CWE-454 (Use of Externally-Controlled Input to Select Classes or Code): the module calls the POSIX standard getenv() to read XRDP_SESSION, DISPLAY, and TMUX in order to classify a session as local or remote and conditionally enforce hardware token requirements. The critical flaw is that getenv() returns attacker-supplied values from the inherited process environment when the module runs inside a setuid binary (sudo, su), because the POSIX standard does not require getenv() to be safe in privilege-escalation contexts. The correct POSIX substitute, secure_getenv() - implemented in the fix commit #384 - returns NULL whenever the real and effective UID/GID differ, blocking untrusted environment data from influencing security decisions. The 0.9.2 release addresses 12 independent security findings uncovered during an ongoing audit, indicating the vulnerability is part of a broader hardening effort rather than an isolated defect.
RemediationAI
Upgrade pam_usb to version 0.9.2 immediately; this release replaces getenv() with secure_getenv() in the PAM context (commit #384, issue #368), which is the direct fix for this vulnerability. The release is available at https://github.com/mcdope/pam_usb/releases/tag/0.9.2 and is described by the vendor as a strongly recommended upgrade. If immediate patching is blocked, a targeted compensating control is to restrict the set of local users permitted to invoke pam_usb-protected setuid binaries - for example, tightening the sudo ruleset to limit which accounts can trigger the vulnerable PAM stack - though this narrows rather than eliminates the attack surface. Additionally, administrators may audit PAM configuration to temporarily remove pam_usb from sudo and su stacks if hardware token enforcement is not strictly required for those paths, accepting the trade-off of reduced authentication assurance until the upgrade is applied. Note that version 0.9.2 also addresses 11 other security findings including TOCTOU races, XXE, symlink-following, and infinite-loop DoS; patching resolves all of these simultaneously.
Authentication bypass in pam_usb before 0.9.1 allows remote unauthenticated attackers to reach the USB hardware-authenti
Authentication bypass in pam_usb prior to 0.9.0 lets a local user defeat the USB hardware-authentication factor by delet
Heap buffer overflow in pam_usb prior to 0.9.1 allows a local attacker with high privileges to corrupt heap memory on 32
XXE injection in pam_usb prior to 0.9.2 enables an attacker with write access to the root-owned configuration file to tr
XPath injection in pam_usb prior to 0.9.0 allows unauthenticated remote attackers to manipulate device-verification quer
PATH hijacking in pam_usb helper tools prior to version 0.9.0 allows a local low-privileged attacker who can manipulate
Symlink race condition in pam_usb prior to 0.9.2 allows a local attacker to redirect one-time pad files to an attacker-c
Non-atomic one-time pad file creation in pam_usb prior to 0.9.2 exposes the core replay-prevention mechanism to a local
Concurrent PAM invocations in pam_usb prior to 0.9.1 expose a process-wide static pointer race condition in src/log.c, w
NULL pointer dereference in pam_usb 0.9.1 and below crashes PAM-integrated authentication services (sudo, login) when lo
Infinite loop denial-of-service in pam_usb 0.9.1 and earlier can permanently hang authentication processes such as sudo,
Insecure deallocation in pam_usb 0.9.1 and below leaves sensitive authentication material - including one-time pad (OTP)
Same technique Code Injection
View allShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-37937