A vulnerability disclosure dropped quietly last week that deserves more attention than it’s getting. libssh2, the open-source SSH client library baked into curl, backup utilities, IoT firmware, and a long tail of network appliances, has a critical remote code execution bug. CVSS 9.2. Every version through 1.11.1 is affected. There is no official patch release yet.

What is libssh2 and why this is a supply chain problem

Before getting into the mechanics of the flaw, it’s worth being clear about what libssh2 is and where it sits in most software stacks, because that context is what makes this more than a standard “update your library” advisory.

libssh2 is a C library that implements the SSH2 protocol on the client side. It handles the full handshake, key exchange, encryption negotiation, and transport layer so that applications do not have to. curl uses it to support SCP and SFTP transfers, making it an omnipresent dependency of almost everything that does automated file transfers over SSH. Backup software relies on it. Network management tools rely on it. IoT device firmware relies on it. It turns up in routers, NAS devices, industrial controllers, and embedded systems that ship their own bundled copy of the library and receive firmware updates on a schedule somewhere between infrequent and never.

That bundling pattern is the problem. When libssh2 has a critical vulnerability, it is not enough to update the package on your Linux host. Every product that statically links or ships its own copy of libssh2 is independently vulnerable, and each of those products requires a separate vendor patch. That is a slow and uneven process. Some vendors will ship an update within days. Others will not respond for months. Some never will.

The bug: what the code’ Supposed to do and where it breaks

CVE-2026-55200 is an out-of-bounds heap write in ssh2_transport_read() which lives in transport.c. Understanding exactly why this is dangerous requires a brief look at how the SSH transport layer works.

When two SSH endpoints connect, they go through a binary packet protocol before any authentication happens. Each packet sent over the wire has a fixed structure: a 4-byte packet_length field that declares how many bytes follow, a 1-byte padding_length, a payload, padding bytes, and an optional MAC. The receiving side reads packet_length first, allocates a buffer of that size, then reads the rest of the packet into that buffer.

The assumption embedded in that design is that packet_length is not out of spec. If it is not and the receiving code does not independently verify that the declared length is within some sane upper bound, then the result is a classic heap overflow.

That is exactly what happens in libssh2 through 1.11.1. The library has an internal maximum packet size, but ssh2_transport_read() fails to enforce it when reading the packet_length field off the wire. An attacker-controlled server sends a packet where packet_length is set to a value far larger than the actual payload. libssh2 allocates a buffer based on the legitimate allocation size for the operation in progress, then attempts to read the declared number of bytes into it. The write goes past the end of that heap buffer, corrupting whatever memory lives adjacent to it.

Controlled heap corruption of this type is the foundation for a large class of memory exploitation techniques. What an attacker does with it depends on the heap layout and the runtime environment, but remote code execution is well within the established range of outcomes from this class of vulnerability.

The attack fires before authentication. It fires during the initial transport negotiation, which happens the moment a client initiates a connection to a server. There is no login prompt, no credential exchange, no session state to establish first. A malicious server just needs the client to connect.

Researcher Tristan Madani found and reported the issue. VulnCheck published the advisory. The root cause analysis is available in the VulnCheck write-up.

The second vulnerability: CVE-2026-55199

A second flaw came out in the same disclosure. CVE-2026-55199 is rated 8.2, classified as high severity, and causes denial of service rather than code execution. It targets the same phase of the connection: the pre-authentication key exchange.

During the initial key exchange, the server can advertise a list of extensions it supports. In a legitimate session, that list is a small number of items. The server sends a count of how many extensions follow, then the extension data. libssh2 reads that count and loops over the declared number of extensions.

The bug is that the library does not sanity-check the extension count before entering the loop. A malicious server sends an absurdly large count value. libssh2 dutifully enters a tight CPU loop trying to process an impossible number of extensions, and stays there. Testing has shown this can consume CPU for over 60 seconds, effectively hanging the connecting client.

The practical impact is significant in any environment that runs automated SSH connections at scale. A monitoring agent, a deployment pipeline, a backup job, any of these that connects to a server the attacker controls or has compromised will spin uselessly and block any subsequent work that depends on it completing. It is not code execution, but it is not harmless either.

the awkward gap between “fixed” and “released”

Both bugs have fixes. The maintainers merged two commits: 97acf3d for CVE-2026-55200 and 1762685 for CVE-2026-55199. Both are on the master branch of the libssh2 GitHub repository. Neither has been packaged into a new official libssh2 release.

That gap between “fixed in a commit” and “released as a version” is a real operational problem. Most package managers and dependency resolution tools work off versioned releases. A commit hash is not a version. Downstream consumers of libssh2 cannot simply point their package manager at a commit and expect it to work cleanly. They need to either build from source against the patched commit, or wait for their distribution or upstream vendor to backport the fix into a proper package.

Linux distributions are doing exactly that. Debian’s security tracker shows a repaired build at version 1.11.1-3 currently in testing. Kali Linux reportedly picked up the fix earlier this year. Other major distributions will follow, but the timelines vary.

For software that bundles its own copy of libssh2, the situation is more complicated. Those products each have their own release cycles, and the vendors have to become aware of the vulnerability, integrate the patch, test it, and ship an update, all before the fix reaches users. That chain takes time, and in some product categories, particularly embedded network devices and legacy industrial software, it may not close at all.

Who is actually exposed

The short answer is: anyone whose software connects to SSH, SCP, or SFTP servers using libssh2 as the underlying transport, running any version through 1.11.1, and where the software can be directed to connect to an attacker-controlled server.

That second condition matters. This is a client-side vulnerability. The attack vector is an attacker who controls or impersonates an SSH server. In practice, that means three broad scenarios.

The first is direct man-in-the-middle attacks against unencrypted or poorly secured network paths. If an attacker can intercept TCP traffic between the libssh2 client and its intended SSH server before the encrypted channel is established, they can inject their own SSH server responses during the handshake, before any host key verification can protect the client.

The second is attacks against clients that connect to SSH servers the attacker directly controls, such as shared hosting environments, managed services, or any case where a user can set up an SSH server that other libssh2 clients will connect to.

The third is attacks against automated systems where the target server’s hostname or IP resolves to something the attacker has compromised, through DNS poisoning, BGP hijacking, or server compromise. A backup job or deployment pipeline that connects to a remote SSH server by hostname is exposed if the attacker can redirect that hostname.

In environments that use SSH strictly on trusted internal networks and verify host keys rigorously, the practical exposure is lower. In environments where clients are connecting to external servers, or where host key verification is disabled or bypassed for convenience, the exposure is higher.

Current Exploitation status

No exploitation in the wild has been confirmed. The vulnerability is not in CISA’s Known Exploited Vulnerabilities catalog. The 30-day EPSS probability, which estimates the likelihood of active exploitation, sits at 0.6%.

That is the current picture. There is no public proof-of-concept code yet. The libssh2 codebase is well-known, the advisory is published, the vulnerable function is identified by name, and the bug class (unchecked heap write from an attacker-controlled length field) is one of the better-understood categories in exploitation research. Writing a working PoC is a matter of when, not whether.

The CVSS score of 9.2 reflects the attack complexity being rated low, the privileges required being none, and the user interaction required being none. Those are the three factors that make an RCE vulnerability operationally dangerous rather than theoretically dangerous. Whenever its exploited, it will not require much from an attacker.

What to do

There are two populations of people reading this, roughly speaking: people who manage servers and development environments directly, and people who use software products that happen to contain libssh2 somewhere in their dependency tree.

For the first group, the action is to identify every application in your environment that links libssh2 for SSH, SCP, or SFTP. On Linux, ldd against any suspected binary will show whether it links against libssh2. For statically linked binaries, strings piped through grep for recognizable libssh2 function names or version strings can help. Once identified, check which version is in use. If it is 1.11.1 or earlier, and if your distribution has a backported package available, update it. If you are building from source, pull from the master branch and verify commit 97acf3d is included before building.

For applications where you do not control the build, you are waiting on the vendor. That is the less comfortable position. You can reduce exposure by hardening your network controls around the connections those applications make over SSH, by auditing which servers they are configured to connect to, and by ensuring host key verification is not disabled.

For the second group, the answer is to push your vendors. Check your software vendors’ security advisories for patches. If you run network devices, backup appliances, or any embedded system that uses SSH, check for firmware updates.

The fix is commit 97acf3d for the RCE and commit 1762685 for the DoS. Any build that does not include those two commits is vulnerable. That is the only question worth asking vendors right now.

This post first appeared at - The CyberSec Guru