GHSA-j48q-4c78-rhf9 CVE-2026-74872 PYSEC-2026-3742
openssl-encrypt: Dynamic .so loading for Whirlpool uses broad glob pattern without integrity verification
- Severity
- 0.0 / 10
- Critical · CVSS 4.0
- Exploit chance (EPSS)
- 0.68%
- Chance of exploitation in the next 30 days. Higher than 52.36% of scored vulnerabilities.
- Known exploited
- No
- Not in CISA's catalog
- Weakness
- CWE-427 Uncontrolled Search Path Element
- Fix
1.4.0- Upgrade openssl-encrypt to this version or later
Description
Severity: HIGH
Summary
The Whirlpool hash implementation in openssl_encrypt/modules/registry/hash_registry.py at lines 570-589 uses glob patterns to find .so modules in site-packages and loads the first match via importlib without verifying module integrity.
Affected Code
for site_pkg in site.getsitepackages():
pattern = os.path.join(site_pkg, "whirlpool*py313*.so")
py313_modules = glob.glob(pattern)
if py313_modules:
module_path = py313_modules[0] # Takes first match
loader = ExtensionFileLoader("whirlpool", module_path)
spec = importlib.util.spec_from_file_location("whirlpool", module_path, loader=loader)
whirlpool_module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(whirlpool_module)
Impact
The glob pattern "whirlpool*py313*.so" is broad and takes the first match without verifying:
- File hash/signature
- File ownership/permissions
- Whether it's a legitimate module
If an attacker can place a malicious .so file matching this pattern in any site-packages directory, it will be loaded and native code executed.
Recommended Fix
- Verify the module's integrity (hash or signature) before loading
- Use a specific filename rather than a glob pattern
- Check file permissions and ownership
Fix
Fixed in commit 963d0d1 on branch releases/1.4.x — added os.path.realpath() to resolve symlinks and validation that found .so files are within known site-packages directories before loading.
Affected versions
PyPI
| Package | Vulnerable | Fixed in |
|---|---|---|
| openssl-encrypt | < 1.4.0 |
1.4.0 |
How to fix
Move to the fixed version or later with your package manager, update the lockfile, and run your tests. If the package only arrives through another dependency, upgrade that dependency first. If none of its releases pulls a fixed version yet, force the version with your package manager's override.
openssl-encrypt PyPI → 1.4.0
- pip
pip install --upgrade "openssl-encrypt>=1.4.0"- poetry
poetry add "openssl-encrypt>=1.4.0"- uv
uv add "openssl-encrypt>=1.4.0"
Severity breakdown
CVSS 4.0 0.0
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N/E:U
- Attack vector
- Network
- Attack complexity
- Low
- Attack requirements
- None
- Privileges required
- None
- User interaction
- None
- Confidentiality (vulnerable system)
- None
- Integrity (vulnerable system)
- High
- Availability (vulnerable system)
- None
- Confidentiality (subsequent systems)
- None
- Integrity (subsequent systems)
- None
- Availability (subsequent systems)
- None
- Exploit maturity
- Unreported
CVSS 3.1 9.8
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
- Attack vector
- Network
- Attack complexity
- Low
- Privileges required
- None
- User interaction
- None
- Scope
- Unchanged
- Confidentiality
- High
- Integrity
- High
- Availability
- High
Weakness
CWE-427: Uncontrolled Search Path Element
The product uses a fixed or controlled search path to find resources, but one or more locations in that path can be under the control of unintended actors.
How to prevent it
- Architecture and Design, Implementation: Hard-code the search path to a set of known-safe values (such as system directories), or only allow them to be specified by the administrator in a configuration file. Do not allow these settings to be modified by an external party. Be careful to avoid related weaknesses such as CWE-426 and CWE-428.
- Implementation: When invoking other programs, specify those programs using fully-qualified pathnames. While this is an effective approach, code that uses fully-qualified pathnames might not be portable to other systems that do not use the same pathnames. The portability can be improved by locating the full-qualified paths in a centralized, easily-modifiable location within the source code, and having the code refer to these paths.
- Implementation: Remove or restrict all environment settings before invoking other programs. This includes the PATH environment variable, LD_LIBRARY_PATH, and other settings that identify the location of code libraries, and any application-specific search paths.
- Implementation: Check your search path before use and remove any elements that are likely to be unsafe, such as the current working directory or a temporary files directory. Since this is a denylist approach, it might not be a complete solution.
- Implementation: Use other functions that require explicit paths. Making use of any of the other readily available functions that require explicit paths is a safe way to avoid this problem. For example, system() in C does not require a full path since the shell can take care of finding the program using the PATH environment variable, while execl() and execv() require a full path.
References
Advisories
Packages
Other links
Timeline
- Published
- Last updated by the source
- Latest EPSS score
Related advisories
| Advisory | Severity | Why it's related |
|---|---|---|
| PYSEC-2026-3803 openssl_encrypt before 1.4.9 fails to validate KDF cost parameters in encrypted file metadata and keystore headers, allowing attackers to trigger unbounded… | High | Also affects openssl-encrypt |
| PYSEC-2026-3965 openssl_encrypt before 1.4.9 fails to validate the memory_cost parameter from identity file protection blocks, allowing attackers to trigger out-of-memory… | Medium | Also affects openssl-encrypt |
| PYSEC-2026-3802 openssl_encrypt before 1.4.9 executes untrusted third-party plugins with insufficient controls: the plugin signature policy defaulted to WARN, so an… | High | Also affects openssl-encrypt |
| PYSEC-2026-3801 openssl_encrypt (pip package openssl-encrypt) before 1.4.9 contains two weaknesses in the portable USB drive feature, whose threat model treats the removable… | Low | Also affects openssl-encrypt |
| PYSEC-2026-3800 openssl_encrypt (pip: openssl-encrypt) versions before 1.4.9 contain a path traversal flaw in PluginSandbox._is_safe_path, which authorized file access using a… | Medium | Also affects openssl-encrypt |
| PYSEC-2026-3964 openssl_encrypt (pip package openssl-encrypt) versions <= 1.4.8 do not redact the keyserver bearer token passed as the positional argument to 'keyserver… | Low | Also affects openssl-encrypt |
| PYSEC-2026-3799 openssl_encrypt (pip: openssl-encrypt) versions <= 1.4.8 use suffix-tolerant fingerprint matching in enroll_trust_key when binding a plugin-signing trust… | High | Also affects openssl-encrypt |
| PYSEC-2026-3781 openssl_encrypt before 1.4.9 fails to prevent namespace collisions between own identities and contacts in IdentityStore, allowing attackers to create shadowed… | Critical | Also affects openssl-encrypt |
MergeHarbor checks every repository's dependencies against this database, ranks what matters by exploitability and reachability, routes it to the owning team and opens the fix pull request.
Check your repos with MergeHarbor