Two vulnerabilities in
libssh2,
the widely embedded client-side SSH library that ships inside
curl/libcurl, many Git builds, the PHP ssh2 extension,
and assorted router/IoT and infrastructure management tooling, were
published to the GitHub Advisory Database and NVD on
June 16-17, 2026, credited to Tristan Madani
(@TristanInSec). CVE-2026-55200 (CVSS 9.2, the NVD
rates it CRITICAL) is an out-of-bounds heap write in
ssh2_transport_read() that fails to bound the
packet_length field: a malicious or
machine-in-the-middle SSH peer can send a crafted packet with an
oversized length, corrupt heap memory, and potentially achieve
remote code execution in the process linking libssh2.
CVE-2026-55199 (CVSS 8.2, HIGH) is a pre-auth
denial of service in the SSH_MSG_EXT_INFO handler in
src/packet.c: a malicious server can set the extension
count to 0xFFFFFFFF during key exchange and pin the
client in a CPU loop for over a minute. All libssh2 releases
through 1.11.1 are affected, and as of this writing there is no
fixed release tag. The fixes exist only as commits on the
master branch (97acf3df for the RCE,
17626857 for the DoS). There are no public reports of
in-the-wild exploitation. The most useful operator action is an
inventory pass: find what links libssh2 in your fleet, and track
your distro's patched build or pin to the fix commits.
Framing note: libssh2 is a client library.
It is not OpenSSH and it is not a server. The realistic threat model
is your software reaching out over SSH and connecting to a
server that is attacker-controlled or sits behind a
machine-in-the-middle position, not an attacker hitting your sshd
from the internet. The CVSS vectors reflect this: both carry
AT:P (Attack Requirements: Present), meaning the
precondition is a libssh2 client establishing a session to the
malicious endpoint. Several aggregator headlines describing this as
thousands of internet-exposed systems open to unauthenticated RCE
conflate it with server-side exposure and overstate it. That does
not make it harmless: automation that clones over SSH, fetches via
SCP/SFTP, or polls network devices through libssh2 can be pointed at
a hostile or spoofed host, and the impact then lands in whatever
process holds the library.
Three things make it worth an inventory pass now rather than
waiting for a tagged release: (1) libssh2 is a
deep transitive dependency. Most operators do not have it on a
mental patch list, yet it rides inside curl, Git's SSH transport
on many platforms, language bindings, and embedded management
agents, so the exposure is wider than the package name suggests.
(2) CVE-2026-55200 is a heap out-of-bounds write
reachable before authentication completes, triggered by data the
remote peer fully controls. Heap-overflow-to-RCE is not guaranteed
in every build (allocator hardening, ASLR, and platform mitigations
all matter), but the vendor advisories and NVD treat code execution
as the realistic worst case, and it is best to assume it on
unhardened or embedded targets. (3) There is no
fixed release. libssh2 1.11.1 is still the latest tag; the fixes
are commits on master. That means "just upgrade to the
patched version" is not yet an option from upstream directly, and
you are dependent on either your distribution's backport or a
pinned build from the fix commits.
1.11.1 string alone does not tell you whether the two
fix commits are included.
Priorities, by how you use libssh2
Triage on two questions: does any of your software link libssh2 as a client, and does that client ever connect to an SSH endpoint you do not fully trust (a third-party host, a device on an untrusted segment, anything reachable across a network an attacker could occupy for a machine-in-the-middle). The closer you are to "yes, yes," the higher this rises.
| Priority | Use of libssh2 | Why |
|---|---|---|
| Higher | libssh2 client connecting to endpoints you do not control, or across untrusted networks (CI/CD that clones or deploys over SSH to external hosts, SCP/SFTP fetches from third parties, automation that polls customer or field devices) | This is the exposure pattern CVE-2026-55200 reaches. The peer controls the packet that triggers the OOB write, and the trigger fires before authentication, so trusting the server's credentials does not help you. A compromised or spoofed endpoint, or a MITM on the path, can attempt heap corruption against the process holding libssh2. Inventory now, track the patched build, and pin trusted host keys so a MITM cannot transparently substitute a hostile server. |
| Higher | Embedded / appliance / IoT firmware that bundles its own libssh2 to manage or reach other devices | Embedded builds are the worst case for heap-overflow-to-RCE: frequently no ASLR, weak or no allocator hardening, long patch latency, and a copy of libssh2 statically linked or vendored into firmware where your distro's backport never reaches. If a field device's management agent connects out through libssh2, treat it as exposed until the vendor ships fixed firmware, and constrain which endpoints it will dial. |
| Medium | curl/libcurl, Git, PHP ssh2, or language bindings on servers and workstations, used against mostly trusted hosts |
Still affected, lower realized risk because the endpoints are usually your own infrastructure. The exposure is the day someone points one of these at a hostile or spoofed host (a malicious repo URL, a typo-squatted hostname, a poisoned CI variable). Patch on your normal package cadence once the fixed build lands, and prefer host-key verification everywhere. |
| Medium | Anything where the only realistic exposure is the DoS (CVE-2026-55199) against a client that connects to semi-trusted servers | Availability-only impact: a malicious or compromised server can stall the client for a minute-plus per connection. Annoying for an interactive tool, more material for automation that opens many sessions or runs on a tight schedule. Same fix; lower urgency than the RCE if the RCE path does not apply to you. |
| Lower | Systems that do not link libssh2 at all, or that only run an OpenSSH/libssh server (not libssh2) | Not affected by these two CVEs. libssh2 is a separate project from OpenSSH and from libssh (the libssh.org library). Confirm you actually have no libssh2 in the dependency graph (see the inventory commands below) before concluding you are clear, because it arrives transitively more often than people expect. |
Categorization source: this prioritization is the
bulletin's own framing, derived from the CVSS vectors (both
AV:N/AC:L/AT:P/PR:N/UI:N, RCE vs. availability-only
impact) and the client-side nature of the library. It is not an
upstream-published severity ranking beyond the base CVSS scores.
Am I affected?
Find libssh2 in your packages (Linux)
Start with the package manager, then widen to linked binaries and vendored copies. On Debian/Ubuntu:
dpkg -l | grep -i libssh2 apt-cache policy libssh2-1
On RPM-based systems (RHEL, Fedora, SUSE). The glob catches
distro-specific names such as libssh2-1 on SUSE, and the
%{RELEASE} field is where a backported fix usually
shows:
rpm -qa 'libssh2*'
rpm -qa --qf '%{NAME} %{VERSION}-%{RELEASE}.%{ARCH}\n' 'libssh2*'
Compare the installed version against your distribution's security
tracker. The upstream string will read 1.11.1 or lower;
a backported fix usually shows as a higher package revision
(for example 1.11.1-3 on Debian) rather than a higher
upstream version, so do not rely on the 1.11.1 string
alone. Confirm the advisory entry for your distro lists both fix
commits as included.
Find linked and vendored copies
Distro metadata misses statically linked and vendored copies. Look for the shared object on disk and for the processes currently holding it open:
ldconfig -p | grep -i libssh2 find / -xdev -name 'libssh2*' 2>/dev/null
To see which running processes currently hold it open:
lsof 2>/dev/null | grep -i libssh2
curl is the most common consumer. Its version banner lists libssh2 when the build links it:
curl --version | tr ' ' '\n' | grep -i ssh2
An empty result means this curl build does not link libssh2 (it may
use OpenSSH-backed SCP differently, or omit SCP/SFTP support). A line
like libssh2/1.11.1 means it does, at that version.
Language bindings and app dependencies
Bindings wrap the same C library and inherit the bug. Check the ones you use:
pip list 2>/dev/null | grep -i ssh2
php -m | grep -i ssh2
php -r 'echo phpversion("ssh2");' 2>/dev/null
For the Python ssh2-python binding and similar, the
relevant question is which libssh2 it was built or bundled against;
a wheel can carry its own copy. For Git, builds vary by platform on
whether the SSH transport uses an external ssh binary or
a linked libssh2 (often via libgit2), so confirm your specific Git
build rather than assuming.
Windows and macOS
On Windows, libssh2 most often arrives bundled inside a vendored
build of curl, Git for Windows, or a third-party application, rather
than as a system package, so inventory means checking the
application's own version banner or its shipped DLLs
(libssh2.dll). On macOS, Homebrew's
brew info libssh2 shows the formula version, but
applications frequently vendor their own copy independent of
Homebrew. In both cases the static/vendored-copy problem dominates:
the fix arrives when each application ships an updated build, not
when a shared system library is patched.
Response
- Inventory first, patch second. Run the checks above across your fleet and build a list of every place libssh2 is linked, including curl, Git, PHP, language bindings, and any vendored or statically linked copies in applications and firmware. The dependency is transitive often enough that the inventory is the real work here; once you know where it is, the patching is routine.
-
Track your distribution's patched build and apply it when
it lands. Because there is no upstream fixed release tag
yet, the cleanest path for distro-packaged libssh2 is the
backport. Watch your distro's security tracker for the package that
lists both fix commits (
97acf3dfand17626857), then update on your normal cadence. Debian's tracker showed1.11.1-3in testing at time of writing; confirm the current state for your release rather than trusting this snapshot. - Verify SSH host keys everywhere a libssh2 client connects. Both bugs require the client to talk to a hostile server. Strict host-key checking (a known-hosts pin, certificate verification, or equivalent in whatever wraps libssh2) is what stops a machine-in-the-middle from transparently swapping in an attacker-controlled server on the path. This is a mitigation that works today, independent of the patch, and is good practice regardless. Confirm your automation is not configured to blindly accept unknown host keys.
- Constrain where untrusted-facing and embedded clients can connect. For automation and field/IoT agents that reach out through libssh2, limit the set of endpoints they will dial (egress allow-lists, fixed target hosts, network segmentation) so a single poisoned URL or compromised endpoint has a smaller chance of steering a vulnerable client at a hostile server. This narrows the attack surface during the window before every vendored copy is patched.
- For vendored and firmware copies, open vendor tickets. Where libssh2 is statically linked into a third-party application or device firmware, your distro backport will never reach it; the fix arrives only when the vendor rebuilds. Identify those products from the inventory, ask each vendor for a build that includes both fix commits, and treat the device or app as exposed in the meantime if it connects out to anything you do not control.
- Watch for a tagged release and for any exploitation signal. A libssh2 release past 1.11.1 that carries both commits is the clean fix for source builds and downstreams; track the project's releases page. There is no confirmed in-the-wild exploitation and no public PoC at time of writing; if that changes, the RCE's pre-auth, peer-controlled trigger makes it worth re-prioritizing, so keep an eye on the CISA KEV catalog and vendor advisories.
The broader pattern
The recurring lesson here is not about SSH specifically, it is about transitive C dependencies that nobody has on a patch list. libssh2 sits one or two layers below the tools operators actually think about, so the hard part of responding is discovery, not remediation. The same shape has shown up repeatedly: a memory-safety bug in a small, ubiquitous C library (the kind that gets vendored into curl, into language runtimes, into appliance firmware) where the real cost is finding all the copies, and the long tail is the statically linked and firmware-embedded instances that a distribution update never touches.
It also reinforces a calibration point worth keeping: a 9.2 CRITICAL on a client library is a different risk than a 9.2 on an internet-facing server. The pre-auth label is real, but "pre-auth" here means the client is attacked before it authenticates the server, so the precondition is reaching out to a hostile peer, not sitting exposed waiting to be hit. Host-key verification, egress control, and knowing your dependency graph are the controls that actually move this risk, and they are available before any patch ships.
At time of writing: there is no upstream fixed release tag, only
the two master commits, so version strings alone are
an unreliable signal of whether a given build is patched; verify
commit inclusion. There is no confirmed in-the-wild exploitation
and no public proof-of-concept. Whether CVE-2026-55200 reliably
reaches code execution as opposed to a crash depends heavily on the
target's allocator, platform mitigations, and build hardening; the
advisories assert RCE as the realistic worst case and this bulletin
follows that, but a given build may only be DoS-able in practice.
The distro status lines are spot checks (Debian, Kali) and not a
complete cross-distribution matrix; check your own distribution.
CISA had not listed either CVE in the KEV catalog as of
publication. The CVE description's abbreviated commit hash
("7acf3df") does not match the actual short hash (97acf3df); this
bulletin uses the full commit IDs from the pull requests to avoid
ambiguity. This guide will be updated if a tagged release ships, if
exploitation is reported, or if the cross-distro patch picture
firms up.
libssh2 through 1.11.1 has a pre-auth heap-overflow RCE
(CVE-2026-55200, CVSS 9.2) and a pre-auth DoS (CVE-2026-55199,
CVSS 8.2), both triggered when a libssh2 client
connects to a malicious or MITM SSH server, and both fixed only as
master commits (97acf3df,
17626857) with no tagged release yet.
Inventory everything that links libssh2 (curl, Git, PHP,
bindings, vendored and firmware copies), track your distro's
backported build or pin to the fix commits, and verify SSH host
keys so a machine-in-the-middle cannot swap in a hostile
server. No confirmed in-the-wild exploitation yet;
prioritize inventory and patch tracking over emergency
internet-exposure response.