Operating system, libraries and runtimes
curl: CVE-2026-92392
curl HTTP/2 Upload Use-After-Free Check
CVE-2026-92392 is a use-after-free in libcurl's HTTP/2 upload handling. A malicious server that receives an upload can corrupt the uploading client's memory, and the reporter turned that into code execution on the client. The attack runs from the server side: the client uploads roughly 135KB over HTTP/2 to the attacker's HTTPS server (whose certificate must validate), the server stalls and resets the stream, and curl reuses a freed handle on retry. Taking over a client needs exact knowledge of its build, architecture, allocator and heap layout, so curl expects most real attempts to end in a crash, and rates the flaw High rather than Critical. Because libcurl is linked by many other programs (git, package managers, language runtimes), the exposure is not limited to the curl command.
The flaw affects curl and libcurl 8.12.0 through 8.22.0 and is not present before 8.12.0. It is fixed upstream in 8.23.0, with branch backports in 8.14.3, 8.16.2 and 8.20.2, and distributions ship their own builds (Debian 13 trixie: 8.14.1-2+deb13u7 via DSA-6558-1; Debian 12 bookworm does not carry the vulnerable code). This script is read-only: it finds what needs updating and reports whether each build is fixed and whether it supports HTTP/2 at all.
curl quick start
-
Download the script. The repository is mirrored on GitHub and Codeberg; pick a base URL.
# BASE from GitHub: https://raw.githubusercontent.com/PrivacySafe/security-patches/refs/heads/main # BASE from Codeberg: https://codeberg.org/PrivacySafe/security-patches/raw/branch/main # curl -fLO "$BASE/curl/curl-oct2026-check.sh" curl -fLO https://raw.githubusercontent.com/PrivacySafe/security-patches/refs/heads/main/curl/curl-oct2026-check.sh -
Read it before running it, then make it executable.
less curl-oct2026-check.sh chmod +x curl-oct2026-check.sh -
See what's exposed. Root is optional, but without it you won't read every library or exec into other users' containers.
sudo ./curl-oct2026-check.sh check -
Look for crashes that suggest someone already tried.
sudo ./curl-oct2026-check.sh hunt
curl commands
| Command | What it does |
|---|---|
check (default) |
Reports every curl command and libcurl on the host, and libcurl inside running containers, with whether each carries the fix and whether the build supports HTTP/2. Changes nothing, root optional. Exits 0 if nothing is exposed, 1 if a vulnerable curl/libcurl is present, 2 if something couldn't be read |
hunt |
Read-only log triage for process crashes that look like this bug: curl segfaults and protection faults, libcurl frames in a backtrace, use-after-free and heap-corruption aborts, and services killed by a crash signal. A failed attack is most likely a crash, so a crash on an outbound HTTP/2 upload is the signal. Exits 0 if nothing matched, 1 if it found something |
version |
Prints the script version. Every command prints it on its first line too |
What the curl check looks at
- The
curlcommand. EverycurlonPATHand the usual locations. It readscurl --version, which reports both the tool version and thelibcurl/X.Y.Zthe tool links, and whether the build advertisesHTTP2. The verdict is on the libcurl version, since that is where the flaw lives. A build with no HTTP/2 support cannot reach the upload path, and is reported as such rather than as exposed. libcurlon the host. Everylibcurl.soon the standard library paths and inldconfig's cache. The soname is alwayslibcurl.so.4, so the version is read from the package build (for a distribution library) or from thelibcurl/X.Y.Zstring the library carries, never by executing it. Each is noted for whether it linksnghttp2(HTTP/2 capability).libcurlinside running containers. For each running Docker or Podman container, thelibcurlthe container actually carries, read from its embedded version string. A rebuild, not a restart, replaces it.
curl patch detection
For a curl or libcurl installed from a Debian or Ubuntu package, the script judges the package build first. It uses a built-in list of known fixed builds plus any you add with FIXED_BUILDS, then the package changelog naming CVE-2026-92392 or DSA-6558-1, because a distribution backports the fix under an older-looking upstream number. The built-in list already carries Debian 13's 8.14.1-2+deb13u7, so a patched trixie host reads as fixed without configuration. For a self-built or bundled library it uses the upstream fix for the version's branch. Builds from 8.12.0 through 8.14.2 need 8.14.3, 8.15.0 through 8.16.1 need 8.16.2, 8.17.0 through 8.20.1 need 8.20.2, and 8.21.0 through 8.22.x need 8.23.0. Anything below 8.12.0 is reported as not affected.
curl mitigation
The fix is to update curl/libcurl and restart the programs that use it. Where you cannot update yet, curl's advice is to avoid HTTP/2 for uploads, because the vulnerable path is HTTP/2 only:
- On the command line, pass
--http1.1. - In an application, set
CURLOPT_HTTP_VERSIONtoCURL_HTTP_VERSION_1_1. curl documents this as a request, since an existing connection on another version may be reused. - A libcurl built without HTTP/2 cannot negotiate it, so it cannot reach the path at all.
curl configuration
| Variable | Default | Purpose |
|---|---|---|
FIXED_BUILDS |
(empty) | Extra fixed distro curl/libcurl builds, space-separated full versions. Checked alongside the built-in known builds, which it does not replace |
CURL_SEGMENTS |
8.12.0:8.14.3 8.15.0:8.16.2 8.17.0:8.20.2 8.21.0:8.23.0 |
introduced:fixed per maintained branch |
CURL_INTRODUCED |
8.12.0 |
Below this the flaw is not present |
SCAN_CONTAINERS |
1 |
0 skips reading libcurl inside running containers |
HUNT_SINCE |
2026-10-01 |
How far back hunt reads the journal |
HUNT_LOGS |
(empty) | Extra log globs for hunt |
Before you run it
- The fix. Update to 8.23.0 (or the 8.14.3 / 8.16.2 / 8.20.2 branch build, or your distribution's fixed build), rebuild anything that bundles libcurl, and restart the programs that use it, since a running process keeps the old library until it restarts.
- The risk is an outbound HTTP/2 upload to a server you don't control. A program on this host that uploads over HTTP/2 to an attacker-controlled HTTPS server is the exposure. A plain server that only receives requests is not the target here.
- A build without HTTP/2 is not a path. The check reports HTTP/2 capability so you can tell, but HTTP/2 is built into most modern curl packages.
- Distribution backports read correctly. A package can carry the fix under an older upstream number, if you know a build is fixed and its changelog doesn't name the CVE, add it to
FIXED_BUILDS. - Containers need their own fix. Each image carries its own libcurl. Rebuild on a fixed base. The script reads the library inside running containers but can't see one installed in an unusual way.
- A development build is not the release. A curl built from git identifies itself as
8.20.2-DEV, a build made before 8.20.2 shipped, so at a fix version the script reports it as unknown (it may or may not carry the fix) instead of fixed. A development build past the fix version is fixed. - An unreadable
curlis reported, not skipped. AcurlonPATHwhose--versionoutput cannot be read is listed as unknown, and the rest of the check still runs. - GNU/Linux only. Library discovery and container inspection assume it.
Red Hat advisories
Red Hat's advisory list (security advisories released 2026-04-01 to 2026-11-03) names the CVEs below. A Red Hat build is judged by its RPM release, not by the upstream version number, because Red Hat backports fixes: the advisory names the release that fixes it. A CVE with no advisory in the list has none for that period, which is not the same as not affected. The current state is on Red Hat's CVE database.
| Advisory | Released | Severity | Package and stream | CVEs on this page |
|---|---|---|---|---|
| RHSA-2026:80349 | 2026-10-11 | Important | rust-1.99.0-1.hum1 (Hummingbird) |
CVE-2026-92392 |
| RHSA-2026:82895 | 2026-10-14 | Important | curl-8.23.0-0.1.hum1 (Hummingbird) |
CVE-2026-92392 |
The Security Patches software and this documentation are dedicated to the public domain under CC0 1.0 Universal. Other pages on privacysafe.app/docs are CC BY-SA 4.0 unless the page says otherwise.