Skip to content

GHSA-j48q-4c78-rhf9 CVE-2026-74872 PYSEC-2026-3742

openssl-encrypt: Dynamic .so loading for Whirlpool uses broad glob pattern without integrity verification

Critical PyPI
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

PackageVulnerableFixed 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

Timeline

  1. Published
  2. Last updated by the source
  3. Latest EPSS score
AdvisorySeverityWhy 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
Is this in your code?

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