
Checks local curl/libcurl builds for CVE-2026-92392 HTTP/2 upload use-after-free exposure, with passive inventory, mounted-image scanning, and a bounded loopback PoC probe.
cve_2026_92392_check.py assesses local curl and libcurl artifacts for
CVE-2026-92392, an HTTP/2 upload
use-after-free in curl/libcurl.
It supports passive local inventory, supplied-banner assessment, non-executing mounted-image scanning, and a bounded loopback HTTP/2 protocol probe. The probe is defensive and non-weaponized. It has no command payload, shellcode, memory-address manipulation, information-leak logic, or RCE payload.
The active probe binds only to 127.0.0.1, accepts no remote target URL or
host, and executes only the selected local curl binary.
The checker separates four different evidence levels:
| Evidence level | What it establishes | What it does not establish |
|---|---|---|
| Build classification | Whether a version-qualified curl/libcurl artifact is outside the upstream affected range, upstream-affected with unknown vendor patch state, or confirmed affected using supplied patch-state evidence | Whether an application actually uses the affected HTTP/2 upload path |
| Runtime exposure context | Whether supplied application facts indicate HTTP/2 uploads can reach an attacker-controlled endpoint | Whether the vulnerability was triggered |
| Protocol stimulus | Whether the local loopback harness delivered both documented reset variants with two uploads on one HTTP/2 connection | A use-after-free, crash cause, or code execution |
| CVE-attributed sanitizer result | Whether the candidate sequence, an AddressSanitizer heap-use-after-free, an upstream-affected artifact identity, and a matching HTTP/2 stack were all observed | Reliability or practical exploitability on another system |
A clean run, an incomplete protocol run, or a non-crashing sanitizer run does not prove that a build is safe.
CVE-2026-92392 affects curl/libcurl HTTP/2 upload handling. During an upload,
an affected build can process an HTTP/2 RST_STREAM carrying either
REFUSED_STREAM or HTTP_1_1_REQUIRED. Buffered upload data can then be
parsed as a new request after the original transfer's HTTP/2 state was
detached. A later HTTP/2 callback can dereference a stale Curl_easy pointer.
The REA comparison used to revise this checker confirmed the relevant cleanup ordering difference:
Curl_conn_ev_data_done, processes pending
handles, and only then calls Curl_req_done.Curl_req_done reaches req_flush, while the HTTP/2 data-done path has
already cleared stream context.Curl_req_done before
Curl_conn_ev_data_done, eliminating that stale ordering.This is implementation evidence supporting the checker's proof model. Vendor patch state still requires independent verification.
The upstream advisory identifies the vulnerable implementation as introduced in curl 8.12.0. The checker classifies upstream releases as follows:
| Release condition | Classification |
|---|---|
| Earlier than 8.12.0 | NOT AFFECTED |
| 8.12.0 through 8.22.0, excluding fixed backports | Upstream affected |
| 8.14 branch at 8.14.3 or later | Fixed backport |
| 8.16 branch at 8.16.2 or later | Fixed backport |
| 8.20 branch at 8.20.2 or later | Fixed backport |
| 8.23.0 or later | NOT AFFECTED |
| Development, snapshot, nightly, or ambiguous version | INDETERMINATE |
A vendor can backport the fix without changing curl's upstream version string. Therefore, an affected upstream version is inventory evidence, not conclusive proof that a vendor build is unpatched.
Use --patch-state only when the downstream semantic-fix state has been
verified through vendor advisories, package changelogs, source comparison, or
another trustworthy artifact-level method.
--patch-state value | Meaning |
|---|---|
unknown | Default. An affected upstream version produces UPSTREAM-AFFECTED VERSION. |
absent | Operator has independently verified the downstream fix is absent. An HTTP/2-capable affected build produces AFFECTED BUILD. |
present | Operator has independently verified the downstream semantic fix is present. This is an operator assertion, not automatic proof of binary equivalence to curl's upstream fix. |
--poc.--poc-proof asan.openssl command only when --tls is used.Active PoC mode refuses scripts, wrappers, unidentified native executables, and PE/Windows binaries. Passive assessment remains available for banners and mounted filesystems.
Inspect the curl binary found in PATH:
python3 cve_2026_92392_check.py
Emit JSON:
python3 cve_2026_92392_check.py --json
Run internal self-tests:
python3 cve_2026_92392_check.py --self-test
python3 -O cve_2026_92392_check.py --self-test
Inspect a selected curl executable and libcurl shared library:
python3 cve_2026_92392_check.py \
--curl-binary /opt/curl/bin/curl \
--libcurl-path /opt/curl/lib/libcurl.so \
--json
Evaluate a trusted curl banner without executing a binary:
python3 cve_2026_92392_check.py \
--version-string 'curl 8.12.0 libcurl/8.12.0 nghttp2/1.61.0' \
--json
A bare version such as 8.12.0 is not accepted as verified curl/libcurl
identity evidence.
The checker deliberately does not contact remote hosts. Obtain the banner through an authorized administrative channel, save it locally, then assess it locally:
ssh [email protected] 'curl --version' > host-curl-version.txt
python3 cve_2026_92392_check.py \
--version-file host-curl-version.txt \
--http2-use unknown \
--untrusted-upload unknown \
--https-certificate unknown \
--json
If application review or a trusted trace establishes that uploads use HTTP/2, can reach an attacker-controlled endpoint, and accept its HTTPS certificate, supply those facts explicitly:
python3 cve_2026_92392_check.py \
--version-file host-curl-version.txt \
--http2-use yes \
--untrusted-upload yes \
--https-certificate yes \
--patch-state unknown \
--json
For cleartext h2c, use --https-certificate not-applicable.
--http2-use yes identifies runtime HTTP/2 use. It does not prove that the
artifact was compiled with HTTP/2 support. Similarly, --untrusted-upload yes
describes application data flow, while --https-certificate yes records the
separate HTTPS trust condition.
Use --root to scan a mounted container image, VM image, or extracted
filesystem without executing discovered files:
python3 cve_2026_92392_check.py \
--root /mnt/rootfs \
--json
The root scan:
curl, curl.exe, and libcurl artifacts only.INDETERMINATE.The build verdict is driven by two conditions:
| Prerequisite | Meaning |
|---|---|
| P1 | A verified curl/libcurl identity and version in the affected upstream range, subject to verified downstream patch state |
| P2 | HTTP/2 support compiled into the assessed artifact |
Runtime exposure is evaluated separately: