CVE-2026-84897 Overview
CVE-2026-84897 affects wolfSSL wolfSSH through version 1.5.0. The flaw resides in src/internal.c, where the server accepts Diffie-Hellman group exchange messages that only a client should receive. Specifically, IsMessageAllowedServer() fails to enforce a direction check across the key exchange message range 30–34. An unauthenticated attacker can send SSH_MSG_KEX_DH_GEX_GROUP (31) after KEXINIT, forcing the server into the client-side handler DoKexDhGexGroup(). That handler performs two 8-round Miller-Rabin primality tests on attacker-supplied values up to 8192 bits, consuming server CPU before any authentication occurs.
Critical Impact
Unauthenticated remote attackers can trigger expensive primality testing on arbitrary wolfSSH servers, enabling pre-authentication CPU exhaustion with trivial attacker cost.
Affected Products
- wolfSSL wolfSSH 1.5.0 (vulnerable to the primality-testing cost path)
- wolfSSL wolfSSH 1.2.0 through 1.4.22 (admits the same message into the client-role path without primality cost)
- wolfSSH builds that do NOT define WOLFSSH_NO_DH_GEX_SHA256, WOLFSSH_NO_DH, or NO_SHA256
Discovery Timeline
- 2026-10-07 - CVE CVE-2026-84897 published to NVD
- 2026-10-07 - Last updated in NVD database
Technical Details for CVE-2026-84897
Vulnerability Analysis
The vulnerability is a Denial of Service condition rooted in missing direction validation during SSH key exchange [CWE-372]. When a wolfSSH server processes the client's KEXINIT, handshake->expectMsgId is not set. In this keying state with no particular message expected, IsMessageAllowedServer() exits its expectation branch without a verdict and falls through to a numeric range check that admits every message id from 30 through 34.
An attacker negotiates diffie-hellman-group-exchange-sha256 and then sends SSH_MSG_KEX_DH_GEX_GROUP (31), a message a server should never receive. The server dispatches the client-side handler DoKexDhGexGroup(), which validates the attacker-supplied group with two 8-round Miller-Rabin primality tests, one on p and one on (p-1)/2. The handler returns success, stores the attacker's prime and generator, generates a Diffie-Hellman key pair, and sends SSH_MSG_KEX_DH_GEX_INIT (32) back to the attacker. Published RFC 3526 safe primes represent the worst-case input and cost the attacker nothing.
Root Cause
The root cause is an incomplete allow-list in IsMessageAllowedServer(). The function was intended to reject messages that only servers send, but it did not enumerate MSGID_KEXDH_REPLY, MSGID_KEXDH_GEX_GROUP, and MSGID_KEXDH_GEX_REPLY. Combined with an unset expectMsgId during the post-KEXINIT window, the message id range check permits client-role messages to reach server code paths.
Attack Vector
The attack is a network-reachable, pre-authentication request. An attacker opens a TCP connection to the wolfSSH server, completes the SSH version banner exchange, sends KEXINIT advertising diffie-hellman-group-exchange-sha256, and then sends message 31 with a 8192-bit RFC 3526 safe prime. The server performs two Miller-Rabin primality tests before responding. Repeated connections amplify CPU consumption. Message 33 is also admitted but rejected before cryptography because no public key check callback is registered on the server.
INLINE static int IsMessageAllowedServer(WOLFSSH *ssh, byte msg)
{
/* Only the server should send these messages, never receive. */
- if (msg == MSGID_SERVICE_ACCEPT) {
+ if (msg == MSGID_SERVICE_ACCEPT ||
+ msg == MSGID_KEXDH_REPLY || /* aliases MSGID_KEXDH_GEX_GROUP */
+ msg == MSGID_KEXDH_GEX_REPLY) {
WLOG(WS_LOG_DEBUG, "Message ID %u not allowed by %s %s",
msg, "server", "ever");
ssh->error = WS_MSGID_NOT_ALLOWED_E;
Source: wolfSSH security patch commit a472f1e
Detection Methods for CVE-2026-84897
Indicators of Compromise
- Inbound SSH sessions that negotiate diffie-hellman-group-exchange-sha256 and transmit message id 31 (SSH_MSG_KEX_DH_GEX_GROUP) before authentication completes.
- Spikes in wolfSSH process CPU utilization correlated with short-lived, pre-auth SSH connections.
- Repeated connections from the same source that terminate during key exchange without reaching authentication.
Detection Strategies
- Deploy network IDS signatures that flag SSH packets containing message id 31 or 33 flowing from client to server during the KEX window.
- Correlate wolfSSH debug logs reporting WS_MSGID_NOT_ALLOWED_E once the patch is applied, as these indicate active probing.
- Baseline normal key exchange durations and alert on sessions where server-side DH computation exceeds expected bounds.
Monitoring Recommendations
- Track per-source connection rates to SSH listeners and rate-limit sources that open many short-lived sessions.
- Monitor CPU time attributable to the wolfSSH service process and alert on sustained elevation without a corresponding authenticated session count.
- Capture packet metadata on port 22 or any custom SSH port exposing wolfSSH to retain evidence of pre-auth KEX message patterns.
How to Mitigate CVE-2026-84897
Immediate Actions Required
- Upgrade wolfSSH to the patched release that includes commit a472f1e extending IsMessageAllowedServer() to reject MSGID_KEXDH_REPLY and MSGID_KEXDH_GEX_REPLY.
- Restrict network exposure of wolfSSH listeners to trusted management networks until the patch is deployed.
- Rebuild affected firmware or embedded images with the fix and roll out through standard update channels.
Patch Information
The fix is published in the wolfSSH repository as commit a472f1e and merged via pull request #1221. The patch rejects client-role KEX replies at the message-allowed check, preventing dispatch into DoKexDhGexGroup() on the server. Reference material for the underlying protocol is in RFC 3526 and RFC 4419.
Workarounds
- Rebuild wolfSSH with WOLFSSH_NO_DH_GEX_SHA256 defined to disable the vulnerable key exchange method.
- Alternatively, build with WOLFSSH_NO_DH or NO_SHA256, both of which imply the above and remove the affected code path.
- Configure upstream firewalls or SSH-aware proxies to drop pre-auth packets containing KEX message ids 31 and 33 from client to server.
# Rebuild wolfSSH with the DH group exchange SHA-256 method disabled
./configure CFLAGS="-DWOLFSSH_NO_DH_GEX_SHA256"
make
make install
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.