Oct 6, 2026·6 min read·5 visits
PyMongo's CSFLE key management parsing evaluates '.sock' suffixes as local Unix domain sockets rather than remote hostnames. Attackers with database write access can exploit this to achieve local SSRF against Unix domain sockets on the application host.
A vulnerability in the Client-Side Field-Level Encryption (CSFLE) component of the MongoDB Python Driver (PyMongo) allows an attacker with database write access to trigger local Unix domain socket connections. By manipulating the Key Management Service (KMS) endpoint configuration inside the key vault collection to end with a '.sock' extension, an attacker forces the application to perform a Server-Side Request Forgery (SSRF) against internal Unix domain sockets.
PyMongo, the official Python driver for MongoDB, supports Client-Side Field-Level Encryption (CSFLE) and Queryable Encryption to allow applications to encrypt fields before transmitting them to the database. This implementation relies on a local or remote Key Management Service (KMS) to wrap and unwrap data encryption keys. These keys are defined by metadata documents stored within a dedicated vault collection inside the MongoDB instance, typically named admin.datakeys.
The vulnerability arises from how the PyMongo driver handles address resolution for these KMS endpoints. During the decryption or encryption pipeline, PyMongo parses the configured endpoint using its internal helper function parse_host(). This function contains legacy routing logic designed to support local Unix domain sockets for MongoDB server connections.
When a KMS endpoint ends with the .sock suffix, the driver improperly treats it as a local filesystem path rather than a remote hostname. This behavior exposes a Server-Side Request Forgery (SSRF) vector categorized under CWE-918. A malicious user who possesses write access to the database's key vault collection can manipulate these endpoint configurations to force the client application to open connections to internal sockets.
The root cause of CVE-2026-96747 resides within the interaction between PyMongo's generalized connection string parsing logic and the CSFLE connection initiation routines. PyMongo's host parsing function, parse_host(), evaluates connection strings to determine the target protocol family. If the input string ends with the suffix .sock, the function skips normal DNS resolution and port validation.
Instead of generating a standard AF_INET or AF_INET6 socket configuration, parse_host() treats the input verbatim as a Unix domain socket path. This returns a resolved address tuple where the protocol family is flagged for Unix IPC. This design was originally intended to simplify local development by allowing developers to pass local socket paths like /var/run/mongodb-27017.sock as the MongoDB URI.
However, the CSFLE engine utilizes this exact same parse_host() routine when establishing connections to external KMS systems. The driver extracts the masterKey.endpoint value directly from the decrypted key metadata retrieved from the database. Because no validation restricts KMS endpoints to TCP/IP hosts, a .sock endpoint is processed without validation. The driver's internal socket creation module _create_connection intercepts the parsed address and attempts to establish an AF_UNIX connection to the specified path on the application host.
The vulnerability was addressed in PyMongo version 4.18.2 by implementing explicit string validation immediately after the host parsing step. In both synchronous and asynchronous implementations of the encryption module, the driver now checks the parsed address structure to prevent Unix domain socket paths from being used as KMS endpoints.
The fix is applied inside pymongo/synchronous/encryption.py and pymongo/asynchronous/encryption.py within the kms_request() method. Below is an annotated visual representation of the patch diff:
# Vulnerable implementation in pymongo/synchronous/encryption.py
address = parse_host(endpoint, _HTTPS_PORT)
sleep_u = kms_context.usleep
# Patched implementation in pymongo/synchronous/encryption.py
address = parse_host(endpoint, _HTTPS_PORT)
# Fix: Intercept and reject any endpoint that resolves to a local socket path
if address[0].endswith(".sock"):
raise ConfigurationError(f"Invalid KMS endpoint {endpoint!r}")
sleep_u = kms_context.usleepThis validation effectively mitigates the vulnerability by raising a ConfigurationError before any socket creation routine can be triggered. However, the driver still relies heavily on the parse_host helper, which continues to accept .sock configurations globally. While this fix successfully secures the CSFLE connection path, developers must ensure that any custom implementations utilizing parse_host for external network resources implement similar validations.
Exploitation of CVE-2026-96747 requires an attacker to achieve specific database-level privileges. Specifically, the adversary must have write privileges (insert or update) on the collection housing the client-side encryption keys, which is typically admin.datakeys. This level of access corresponds to the Low Privileges requirement specified in the CVSS metrics.
Once access is established, the attacker identifies a target data key document inside the collection and updates the masterKey.endpoint field. The attacker sets this field to point to a sensitive Unix domain socket on the application server. The diagram below illustrates the communication flow during an exploit attempt:
After the database is poisoned, the attack is triggered passively when a legitimate user or application process executes a query requiring CSFLE encryption or decryption. PyMongo automatically fetches the poisoned key from the key vault to decrypt the required fields. During the key unwrapping phase, the driver parses the malicious KMS endpoint, resolves it to the local Unix socket, and establishes a connection.
The direct impact of successful exploitation is a local Server-Side Request Forgery (SSRF) that allows the driver to interact with arbitrary Unix domain sockets on the host operating system. Depending on the environment, this could allow an attacker to connect to critical local sockets. Examples of target sockets include container management runtimes like /var/run/docker.sock or local application IPC sockets.
However, the attack is bound by strict constraints inherent to PyMongo's connection lifecycle. Because the driver expects a secure KMS endpoint, it initiates a TLS handshake immediately upon establishing the socket connection. The only data transmitted over the Unix domain socket is the binary payload of a standard TLS ClientHello message.
This limitation prevents the attacker from transmitting arbitrary commands, such as HTTP REST API calls or custom socket commands. As a result, direct remote code execution or privilege escalation via container APIs is not feasible through this vector alone. The threat is primarily limited to probing for socket existence, triggering socket resource exhaustion, or inducing unexpected application state changes or crashes.
The recommended remediation path is upgrading PyMongo to version 4.18.2 or later, which completely disables Unix socket connections for KMS endpoints. In environments where an immediate upgrade is not feasible, security administrators should implement strict role-based access control (RBAC). Restricting write access to the key vault collection prevents unauthorized modifications to the KMS endpoints.
Additionally, network and system-level hardening should be deployed to minimize the attack surface of local sockets. If the application runs within a containerized environment, avoid mounting critical sockets like docker.sock inside the container namespace. Utilizing container security profiles, such as AppArmor or SELinux, can also restrict the application's ability to interact with host-level IPC mechanisms.
Finally, auditing should be enabled on the MongoDB database to track all write operations targeting the key vault collections. Any configuration changes that introduce non-standard endpoints, especially those ending with the .sock suffix, should trigger high-priority alerts within security information and event management (SIEM) systems.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
PyMongo (MongoDB Python Driver) MongoDB | >= 3.9.0, < 4.18.2 | 4.18.2 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-918 (Server-Side Request Forgery) |
| Attack Vector | Network (AV:N) |
| CVSS v3.1 Score | 5.0 (Medium) |
| Exploit Maturity | none (no public PoC available) |
| CISA KEV Status | Not Listed |
| Privileges Required | Low (requires write access to key vault) |
| Impact Category | Low Confidentiality / Information Disclosure via SSRF |
The web server receives a URL or similar request pointing to an upstream service and retrieves the representation of this resource, without sufficiently ensuring that the request is directed at the intended destination.
A critical Denial of Service (DoS) vulnerability exists in @socket.io/cluster-engine before version 0.1.1. Unauthenticated remote attackers can crash the server process by supplying inherited prototype property names as session identifiers.
A critical double-free vulnerability exists in the Transparent Inter-Process Communication (TIPC) module of the Linux kernel, specifically within the fragment reassembly implementation in `tipc_buf_append()`. This vulnerability can be triggered locally or remotely to cause kernel heap corruption, leading to local privilege escalation or denial of service.
CVE-2026-72137 is a critical double-free vulnerability in the Linux kernel's XFRM (IPsec) subsystem. The vulnerability occurs when the kernel attempts to send NAT keepalive packets over UDP. Under specific transmission failure conditions, both the downstream networking stack and the upstream keepalive dispatcher attempt to free the same socket buffer (sk_buff) structure, leading to kernel memory corruption, denial of service, or potential local privilege escalation.
A critical host injection vulnerability exists in PyMongo's connection string parser prior to version 4.18.2. The parser globally decodes percent-encoded characters in the host portion before splitting on delimiters, allowing attackers to inject arbitrary servers into the database client's connection pool.
An integer overflow vulnerability exists in PyMongo's bundled C extension (bson/buffer.c) when serializing abnormally large documents. Due to compiler optimizations utilizing standard C Undefined Behavior rules, memory overflow validation checks are completely removed during compilation, enabling an attacker to trigger a heap-based out-of-bounds write.
CVE-2026-102827 is an argument injection bypass vulnerability in the node.js simple-git package where the default blockUnsafeOperationsPlugin fails to detect abbreviated Git command options. Attackers can bypass validations using prefixes like --receive-p or --exe, which native Git subsequently expands to dangerous options, leading to remote command execution.