A critical authentication bypass in OpenSSH (CVE-2025-26465) has lurked undetected since 2014, allowing attackers to impersonate any SSH server when a rarely-enabled option is configured. The vulnerability affects all releases from 6.8p1 through 9.9p1.
.png&w=3840&q=75)
A security researcher at Qualys has uncovered a vulnerability in OpenSSH that has existed for over a decade, allowing an attacker positioned on the network path to completely bypass SSH host-key verification and impersonate any server. While the flaw requires a specific configuration to exploit, its presence in every OpenSSH release from 6.8p1 (December 2014) through 9.9p1 (January 2025) means millions of SSH installations worldwide have been silently vulnerable. The bug was introduced by commit 5e39a49, which added support for the RevokedHostKeys feature but inadvertently created a logic error in the host-key verification callback that would go unnoticed for 3,864 days.
On February 18, 2025, the Qualys Threat Research Unit disclosed two related vulnerabilities in OpenSSH: CVE-2025-26465 (the man-in-the-middle bypass) and CVE-2025-26466 (a pre-authentication denial-of-service). The MITM flaw is a textbook case of incorrect error handling—a single missing check that transforms a routine verification failure into a security catastrophe.
The vulnerability only manifests when the OpenSSH client option VerifyHostKeyDNS is set to "yes" or "ask". This option, disabled by default on nearly all Linux distributions, enables DNS-based host-key verification via DNSSEC-signed SSHFP records. When enabled, the client queries DNS for a fingerprint of the server's public key and uses it as an additional trust anchor. However, a logic error in the function causes the client to misinterpret certain error codes as successful verification, allowing an attacker who can manipulate DNS responses—or simply present a forged host key—to bypass the entire SSH authentication handshake.
verify_host_key_callback()Qualys researchers demonstrated that the bug could be reliably triggered by exhausting the client's memory during the key-exchange phase, forcing the verification routine to return an allocation-failure error code that the callback incorrectly treats as success. The attack requires an on-path position (classic man-in-the-middle) but no user interaction, making it particularly dangerous for environments that have intentionally enabled DNS-based verification or for platforms like FreeBSD, which enabled VerifyHostKeyDNS by default for nearly a decade (September 2013 to March 2023).
The core of the vulnerability lies in how OpenSSH handles return codes from the host-key verification routine. When VerifyHostKeyDNS is enabled, the client performs an additional verification step:
VerifyHostKeyDNS=yes, the client queries DNS for SSHFP records (RFC 4255) that contain fingerprints of the server's key.verify_host_key(), which in turn calls sshkey_from_private() to load the server's key from memory.verify_host_key_callback(), which checks the return value.Here's where the bug occurs. The callback function only checks for a return value of -1 (representing a generic failure, such as SSH_ERR_SIGNATURE_INVALID). Any other error code—including -2 (SSH_ERR_ALLOC_FAIL, returned when memory allocation fails)—is ignored, and the function returns success.
1// Simplified pseudo-code of the vulnerable logic:2int verify_host_key_callback(const char *host_key) {3 int result = verify_host_key(host_key);4 5 // BUG: Only checks for -1; any other error is treated as success6 if (result == -1) {7 return FAILURE;8 }9 return SUCCESS; // Incorrectly returns success for errors like -210}An attacker can force sshkey_from_private() to return -2 by exhausting the client's memory. The Qualys proof-of-concept achieves this by:
SSH2_MSG_PING packets during the initial key exchange (≈234 MB total).sshkey_from_private() fails with SSH_ERR_ALLOC_FAIL (-2).verify_host_key_callback() treats -2 as success and accepts the attacker's host key.This is a classic "goto-out" error-handling pattern gone wrong. When the RevokedHostKeys feature was added in 2014, the developer forgot to reset the error code before jumping to the cleanup label, causing downstream callers to misinterpret the result.
A successful exploitation follows this sequence:
1┌─────────────────────────────────────────────────────────────┐2│ 1. Attacker gains on-path position (ARP spoof, rogue Wi-Fi, │3│ compromised router, etc.) │4└─────────────────────────────────────────────────────────────┘5 │6 ▼7┌─────────────────────────────────────────────────────────────┐8│ 2. Victim SSH client has VerifyHostKeyDNS=yes/ask │9└─────────────────────────────────────────────────────────────┘10 │11 ▼12┌─────────────────────────────────────────────────────────────┐13│ 3. Victim initiates SSH connection to legitimate server │14└─────────────────────────────────────────────────────────────┘The memory-exhaustion component (CVE-2025-26466) is optional; the core bypass (CVE-2025-26465) can theoretically be triggered by any condition that causes sshkey_from_private() to return an error other than -1. However, the PING-flood technique provides a reliable, repeatable exploitation path.
OpenSSH (upstream) | OpenSSH client | 6.8p1 – 9.9p1 (inclusive) | 9.9p2 |
Red Hat | RHEL 8 (all architectures) | All releases shipping OpenSSH ≤9.9p1 | RHSA-2025:16823 |
Red Hat | RHEL 9 / 9.4 EUS / 9.6 EUS | All releases shipping OpenSSH ≤9.9p1 | RHSA-2025:3837, RHSA-2025:6993 |
Red Hat | OpenShift Container Platform 4 (RHCOS) | All RHCOS releases with OpenSSH ≤9.9p1 | RHSA-2025:16823 |
Debian | openssh (Bullseye) | 1:8.4p1-5+deb11u3 and earlier | 1:8.4p1-5+deb11u5 |
Debian | openssh (Bookworm) | 1:9.2p1-2+deb12u5 and earlier |
The vulnerability affects any system running OpenSSH 6.8p1 or later where VerifyHostKeyDNS is enabled. While the option is disabled by default on most platforms, there are notable exceptions:
Given OpenSSH's ubiquity—it is the de facto standard for remote administration on Linux, BSD, macOS, and increasingly Windows—the potential attack surface is enormous. However, the requirement for VerifyHostKeyDNS to be enabled means the practical exposure is limited to a subset of deployments. Administrators who have explicitly enabled the option (or are running vulnerable FreeBSD releases) should treat this as a critical, drop-everything-and-patch issue.
The Qualys team successfully demonstrated a working proof-of-concept that reliably triggers the bypass. The attack requires:
VerifyHostKeyDNS=yes or VerifyHostKeyDNS=ask. On most platforms this is off by default, but:As of January 30, 2026, there are no confirmed reports of in-the-wild exploitation of CVE-2025-26465. However:
The lack of observed exploitation is likely due to:
VerifyHostKeyDNS.That said, the threat model is severe for affected systems:
While no threat actors have been publicly attributed to exploiting this vulnerability, the profile of the flaw makes it attractive to:
The fact that the bug existed for over 10 years undetected raises the question: could it have been exploited in the past without anyone knowing? The answer is almost certainly yes—MITM attacks are notoriously difficult to detect retroactively, and a sophisticated attacker who knew about the bug could have used it to compromise high-value targets without leaving forensic evidence.
yes or ask, disable it immediately by adding or changing the line to:VerifyHostKeyDNS was enabled by default and treat all SSH clients as vulnerable until patched.1# RHEL 82sudo dnf update openssh openssh-clients openssh-server34# RHEL 95sudo dnf update openssh openssh-clients openssh-server1sudo apt update2sudo apt install --only-upgrade openssh-client openssh-server1# Apply errata patch for OpenBSD 7.62cd /tmp3ftp https://ftp.openbsd.org/pub/OpenBSD/patches/7.6/common/008_ssh.patch.sig4signify -Vep /etc/signify/openbsd-76-base.pub -x 008_ssh.patch.sig \5 -m - | (cd /usr/src && patch -p0)6cd /usr/src/usr.bin/ssh7make obj8make9make install1wget https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-9.9p2.tar.gz2wget https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-9.9p2.tar.gz.asc3# Verify signature (see OpenSSH website for GPG key)4gpg --verify openssh-9.9p2.tar.gz.asc openssh-9.9p2.tar.gz5tar xzf openssh-9.9p2.tar.gz6cd openssh-9.9p27./configure --prefix=/usr --sysconfdir=/etc/ssh8make9sudo make installIf you cannot patch immediately, the following workarounds provide full mitigation for CVE-2025-26465:
StrictHostKeyChecking yes and maintain an accurate ~/.ssh/known_hosts file. This does not mitigate the vulnerability directly, but it reduces the attack surface by requiring manual verification of host keys.While the MITM bypass (CVE-2025-26465) is a client-side issue, the related memory-exhaustion DoS (CVE-2025-26466) affects SSH servers. To limit the impact of PING-flood attacks, configure the following in /etc/ssh/sshd_config:
1# Limit pre-auth connection time2LoginGraceTime 3034# Limit concurrent unauthenticated connections5MaxStartups 10:30:6067# Enable per-source-IP penalties (OpenSSH ≥9.8p1)8PerSourcePenalties yes9PerSourceNetBlockSize 24:64After editing sshd_config, restart the SSH daemon:
1sudo systemctl restart sshdTo detect potential exploitation attempts or successful attacks:
CVE-2025-26465 is a sobering reminder that even the most battle-tested, security-critical codebases can harbor subtle, high-impact bugs for years. OpenSSH is maintained by some of the most skilled developers in the world, undergoes regular audits, and is deployed on hundreds of millions of systems. Yet a single missing error-code check—introduced by a seemingly innocuous refactoring in 2014—created a critical authentication bypass that went undetected for over a decade.
Several lessons emerge from this incident:
The fact that VerifyHostKeyDNS is disabled by default on most platforms is the single biggest reason this vulnerability has not caused widespread compromise. If the option had been enabled by default—as it was on FreeBSD for nearly 10 years—the impact would have been catastrophic. This reinforces the principle that security-sensitive features should default to off unless there is a compelling reason to enable them.
The VerifyHostKeyDNS feature was designed to leverage DNSSEC to provide an additional trust anchor for SSH host keys. In theory, this is a good idea: if DNS is properly secured with DNSSEC, SSHFP records can provide automatic, cryptographically-verified host-key validation. In practice, however:
The takeaway: DNS-based authentication should be treated as a convenience feature, not a security enhancement. Administrators who enable VerifyHostKeyDNS should understand they are trading a small usability improvement for a significant increase in attack surface.
The root cause of CVE-2025-26465 is a textbook example of incorrect error handling. The developer who wrote the original code assumed that verify_host_key() would only return -1 on failure, but the function can actually return multiple different error codes depending on the failure mode. By only checking for -1, the code silently ignored all other errors—including allocation failures, format errors, and signature validation failures.
This pattern is disturbingly common in C codebases, where functions often return 0 for success and negative values for various error conditions. Developers must be vigilant about checking all possible error codes, not just the most common one. Modern static analysis tools (e.g., Coverity, Clang Static Analyzer) can catch many of these bugs, but they are not foolproof—code review and comprehensive testing remain essential.
The Qualys proof-of-concept cleverly leverages a memory-exhaustion attack (CVE-2025-26466) to reliably trigger the error-code path that bypasses verification. This technique—forcing an application into an out-of-memory condition to induce unexpected behavior—is not new, but it is often overlooked by developers who assume that memory allocation will "just work" in normal operation.
The broader lesson: resource exhaustion attacks are not just denial-of-service attacks. They can also be used to trigger logic errors, bypass security checks, or escalate privileges. Developers should:
The disclosure of CVE-2025-26465 and CVE-2025-26466 has prompted renewed scrutiny of OpenSSH's codebase. Security researchers are now actively auditing other areas of the code for similar error-handling bugs. Key areas of concern include:
ssh -A) is a frequent source of vulnerabilities due to its complexity and the sensitive nature of forwarded credentials.Administrators should stay vigilant for future OpenSSH security updates and consider subscribing to the OpenSSH security mailing list for early notification of new vulnerabilities.
OpenSSH is not the only SSH implementation in wide use. Other implementations, including:
...may have similar vulnerabilities. The disclosure of CVE-2025-26465 should prompt security teams to audit all SSH implementations in their environment, not just OpenSSH.
The OpenSSH VerifyHostKeyDNS bypass is a stark reminder that security is a process, not a destination. Even the most mature, well-audited software can harbor critical bugs. Organizations must maintain a culture of continuous improvement, where:
The fact that this vulnerability existed for 10 years without causing widespread damage is partly luck, partly good default configuration, and partly the result of a security community that rapidly coordinated a response once the bug was discovered. We should not count on being so fortunate next time.
Patch your OpenSSH installations now. Verify that VerifyHostKeyDNS is disabled. And remember: the next critical bug is probably already hiding in plain sight, waiting to be discovered.
1:9.9p2-1 |
Ubuntu | openssh-client (24.04 LTS) | 1:9.6p1-3ubuntu13.8 | 1:9.6p1-3ubuntu13.8 (back-port) |
Ubuntu | openssh-client (22.04 LTS) | 1:8.9p1-3ubuntu0.11 | 1:8.9p1-3ubuntu0.11 (back-port) |
Ubuntu | openssh-client (20.04 LTS) | 1:8.2p1-4ubuntu0.12 | 1:8.2p1-4ubuntu0.12 (back-port) |
Ubuntu | openssh-client (18.04 LTS) | 1:7.6p1-4ubuntu0.7+esm4 | 1:7.6p1-4ubuntu0.7+esm4 (ESM) |
SUSE | openssh (SLES 15) | openssh-7.2p2-81.26.1, 8.4p1-8.16.1, 9.6p1-3.1 | openssh-7.2p2-81.26.1+, 8.4p1-8.16.1+, 9.6p1-150600.6.15.2+ |
OpenBSD | OpenSSH (OpenBSD 7.6) | All versions up to 9.9p1 | OpenBSD 7.6 errata 008 |
Apple | macOS Sonoma / Sequoia | OpenSSH ≤9.9p1 (bundled) | macOS Sonoma 14.7.6, macOS Sequoia 15.5 |
FreeBSD | OpenSSH (base system) | All releases where VerifyHostKeyDNS=yes by default (Sep 2013 – Mar 2023) | FreeBSD updates after Mar 2023 |
NetApp | Various appliances | Embedded OpenSSH 6.8p1–9.9p1 | Vendor firmware updates (pending) |