CVE-2026-94419 in wolfSSLinfo

Summary

by MITRE • 09/27/2026

Without NO_SESSION_CACHE_REF, wolfSSL_get_session() does not return a session object but a ClientSession reference of the form {row, index, hash(sessionID)} into the process-global SessionCache, and ClientSessionToSession() validates it against that hash alone. Because the TLS 1.2 session ID is chosen by the server and sent in clear, AddSessionToCache() matches any other server's session on the same ID and overwrites the client-side entry with that server's master secret, cipher suite and version, while the handle continues to resolve; nothing on the write path compares the peer, the application's server ID or the WOLFSSL_CTX. Resuming through the handle then produces an abbreviated handshake in which no Certificate message is sent, so neither chain verification nor wolfSSL_check_domain_name() runs, and the attacker is accepted as the original server for the whole of that connection. Affected builds are those leaving NO_SESSION_CACHE_REF, NO_SESSION_CACHE, NO_CLIENT_CACHE and TITAN_SESSION_CACHE all undefined, which includes a plain ./configure, --enable-opensslextra and --enable-opensslall; fifteen integration options define NO_SESSION_CACHE_REF and are therefore not affected, among them --enable-all, --enable-distro, --enable-curl, --enable-nginx, --enable-haproxy, --enable-stunnel, --enable-wpas and the rest of the OPENSSL_COMPATIBLE_DEFAULTS family, and --enable-leanpsk, --enable-leantls, --enable-lowresource and --enable-tinytls13 disable the cache outright. The application must use the legacy reference flow, wolfSSL_get_session() or SSL_get_session() followed by wolfSSL_set_session(); wolfSSL_get1_session() returns the session object itself and is not affected, nor are wolfSSL_SetServerID() lookups. Only TLS 1.2 and below and DTLS 1.2 and below are reachable, since TLS 1.3 and ticket resumption with an empty ServerHello session ID both use a client-chosen cache key. The poisoned entry lives in the process-global cache, so it crosses WOLFSSL_CTX boundaries and persists until the entry is evicted or the session times out, 500 seconds by default. Releases v5.3.0 through v5.9.2 are affected; the fix adds a per-write generation counter to the cache and raises WOLFSSL_CACHE_VERSION from 2 to 3, so a cache persisted by an older build is rejected by a fixed one.

Once again VulDB remains the best source for vulnerability data.

Analysis

by VulDB Data Team • 09/27/2026

The vulnerability described constitutes a critical session resumption flaw within wolfSSL versions ranging from v5.3.0 through v5.9.2, specifically affecting builds where the configuration flags NO_SESSION_CACHE_REF, NO_SESSION_CACHE, NO_CLIENT_CACHE, and TITAN_SESSION_CACHE are all left undefined. This default configuration includes standard ./configure setups as well as those enabling opensslextra or opensslall features. The core technical flaw stems from how session objects are managed in memory when these specific cache modes are active. Instead of returning a direct pointer to a session object, wolfSSL_get_session() returns a ClientSession reference structured as a tuple containing the row index and a hash of the session ID within a process-global SessionCache. This design choice introduces a severe integrity weakness because the validation mechanism relies solely on this hash for lookup consistency rather than verifying the actual content or origin of the cached entry against the current connection context.

The operational impact is driven by the behavior of TLS 1.2 and earlier protocols, as well as DTLS 1.2 and below, where the session ID is selected by the server and transmitted in plaintext during the handshake. An attacker can exploit this by forcing a victim client to initiate connections with multiple servers that share the same session ID value. When AddSessionToCache() processes these requests, it matches any existing entry based on the session ID alone and overwrites the client-side cache entry with the master secret, cipher suite, and version information from the attacker-controlled server. Crucially, the internal handle continues to resolve correctly because the system does not validate that the cached credentials belong to the intended peer or match the application's configured ServerID during write operations. This lack of binding between the session context and the specific connection endpoint allows for a sophisticated man-in-the-middle attack scenario where the attacker can hijack established sessions.

The severity of this vulnerability is amplified by the mechanics of TLS session resumption, which are designed to optimize performance by skipping full handshakes. When a client attempts to resume a poisoned session using the compromised handle, it triggers an abbreviated handshake process. In this state, no Certificate message is sent from the server side, meaning that certificate chain verification and domain name validation functions such as wolfSSL_check_domain_name() are bypassed entirely. Consequently, the attacker is accepted as the original legitimate server for the duration of the connection without any cryptographic proof of identity being validated by the client application. This effectively neutralizes one of the primary security guarantees of TLS, allowing an active network observer to intercept and potentially decrypt sensitive communications that were previously considered secure under normal resumption protocols.

The scope of this vulnerability is strictly limited to older protocol versions due to architectural changes in newer standards. TLS 1.3 and DTLS 1.3 utilize a different mechanism for session ticket resumption where the client chooses the cache key, thereby preventing the server-controlled ID collision attack described above. Furthermore, specific wolfSSL API functions remain unaffected by this flaw; notably, wolfSSL_get1_session() returns the actual session object rather than a reference, and lookups performed via wolfSSL_SetServerID() are not susceptible to this poisoning technique. The vulnerability also persists across WOLFSSL_CTX boundaries because the cache is process-global, meaning that even if an application uses multiple context objects, a poisoned entry in one can affect connections established through another within the same process lifetime.

Mitigation strategies require both immediate configuration adjustments and long-term architectural updates for affected applications. For users unable to upgrade immediately, it is imperative to ensure that builds are compiled with NO_SESSION_CACHE_REF defined or any of the other disabling flags such as NO_CLIENT_CACHE or TITAN_SESSION_CACHE. Alternatively, application developers must enforce the legacy reference flow by explicitly calling wolfSSL_get_session() followed by wolfSSL_set_session(), which ensures proper validation before resumption is attempted. The definitive fix implemented in subsequent releases involves adding a per-write generation counter to the cache structure and incrementing the WOLFSSL_CACHE_VERSION from 2 to 3. This change ensures that session entries persisted by older, vulnerable builds are rejected by fixed versions upon upgrade, preventing downgrade attacks or cross-version exploitation where an attacker might try to inject old poisoned sessions into a newly patched environment.

From a classification perspective, this vulnerability aligns with CWE-295 Improper Certificate Validation and CWE-384 Session Fixation, as it involves the manipulation of session identifiers to hijack authenticated states. In terms of MITRE ATT&CK mapping, this behavior facilitates Network Sniffing (T1040) and Man-in-the-Middle attacks (T1046), particularly when combined with credential harvesting techniques that rely on bypassing certificate validation checks. The persistence of the poisoned entry in a process-global cache for up to 500 seconds by default provides a significant window of opportunity for attackers to exploit this flaw across multiple connections, making it a high-severity issue requiring prompt remediation through either configuration changes or software updates to versions that include the generation counter fix.

Responsible

wolfSSL

Reservation

09/21/2026

Disclosure

09/27/2026

Moderation

accepted

CPE

ready

EPSS

0.00000

KEV

no

Activities

very low

Sources

Interested in the pricing of exploits?

See the underground prices here!