Skip to content

libcurl coordinated client-side wave — Negotiate redirect leaks, connection-reuse key gaps, cookie/HSTS cache poisoning, and Early-Hints file overwrite

Source: hourly offensive-security scan, 2026-10-20 21:31Z GitHub Advisory feed — a coordinated ~22-advisory libcurl/curl release. All advisories landed with empty GHSA package/version fields and unknown severity; the vendor security page is the canonical band source. Do not version-fingerprint from the GHSA records.

This wave is the mirror image of everything on the June 4 Axios redirect-credential page: instead of web-app frameworks leaking browser credentials across redirects, the HTTP client every scanner, bounty-recon pipeline, CI job, and agent stack shells out to leaks the operator's own credentials, writes files, and poisons its own on-disk state when it talks to a malicious server or sits behind a malicious proxy.

Authorized validation only

Prove everything against owned malicious-server harnesses (a fake origin + a fake proxy + a capture sink) with synthetic credentials, disposable cookie jars and HSTS caches, and temp-file targets. Never test Negotiate/Kerberos legs against real domain controllers or third-party hosts, never poison shared caches, never let a canary overwrite a real file.

Leg inventory (grouped by reusable axis)

A. Credential egress to attacker-chosen destinations

  • Redirect to a userinfo URL re-sends a freshly minted Kerberos ticket to any host — GHSA-qqmr-6r9w-pmx5 / CVE-2026-94265. On an HTTP redirect whose target contains username:password, curl erroneously retains the original host's Negotiate auth state and transmits it to the redirect target — a malicious server forces curl to generate a fresh ticket under the client process's ambient identity for an untrusted third-party host, bypassing the domain scoping --location-trusted normally enforces. This is the HTTP-client equivalent of an NTLM-relay harvest: one malicious response, one ambient-identity ticket.
  • Ambient credentials follow a redirect to an unrelated origin — GHSA-x2p4-rxj5-99w6 / CVE-2026-86413. First transfer authenticates with an ambient user; the redirect chain hands the credential details to a second, unrelated origin.
  • Ambient credentials dispatched over a connection Negotiate-authenticated for a different origin — GHSA-34qg-cqjx-hpwx / CVE-2026-87861. Request for origin B rides origin A's already-authenticated Negotiate connection; the intended per-origin credential never gets used, and origin A's auth context answers B's request.
  • Malicious CONNECT proxy answers 401 instead of 407 and harvests the origin's credentials — GHSA-6qvf-c7g3-j256 / CVE-2026-86414. A proxy that replies to CONNECT with 401 WWW-Authenticate: (origin status code, not 407 Proxy-Authenticate:) tricks libcurl into sending the origin's Basic password or Negotiate/Kerberos ticket to the proxy itself. Status-code-family confusion is the discriminator the credential router should check; it doesn't.
  • CURLOPT_AWS_SIGV4 set to NULL does not disable SigV4 — GHSA-57hx-469r-xq3r / CVE-2026-86409. The next transfer on the same handle keeps signing and sends Authorization: AWS4-HMAC-SHA256 … to whatever URL is set next — handle-reuse state leak of a live AWS credential header.
  • CURLINFO_EFFECTIVE_URL can report a URL containing credentials that neither the input nor the redirect URL had — GHSA-75f7-vf86-pvgm / CVE-2026-94266. Anything that logs the effective URL (recon pipelines everywhere) can be made to log credentials the application never supplied.

B. Connection-reuse keys missing identity dimensions (four independent legs, one axis)

  • Automatic client certificate is not part of the reuse match — GHSA-4g5c-8qrq-wcmw / CVE-2026-86415. A cached, already-authenticated Schannel connection is handed to a transfer that was redirected to a different origin even though the code explicitly disabled the auto-client-cert option for that transfer to prevent exactly this.
  • Pooled FTP control connection crosses STARTTLS/client-cert state — GHSA-533v-mrfx-494r / CVE-2026-86411. An ftp:// + CURLUSESSL_NONE transfer reuses a handle's pooled control connection that a previous easy handle upgraded with STARTTLS and authenticated by client certificate — no new handshake, no new login; the server keeps authorizing under the first handle's certificate identity.
  • --interface / CURLOPT_INTERFACE bindings (if!, host!, ifhost!) are not in the reuse key — GHSA-9644-8jhv-gxgm / CVE-2026-107929. A later transfer asking for a different source silently reuses the earlier connection and egresses from the earlier transfer's source address — breaks IP-pinned identity, v6-vs-v4 pinning, and any "different source = different socket" assumption.
  • TFTP direction confusion exfiltrates prior handle data — GHSA-9rxv-c97x-mrjr / CVE-2026-92389. A malicious TFTP server responds to a download in a way that flips the client into transmit mode; libcurl then consumes and transmits from the handle's persistent CURLOPT_READDATA pointer — including data left from unrelated prior operations such as an HTTP POST executed on the reused handle. Cross-protocol, cross-operation data leak through handle reuse.

C. TLS-backend-specific validation bugs (build = attack surface, again)

  • wolfSSL builds: pinned-public-key validation against a key the peer does not possess — GHSA-wq9f-qmpx-2cc8 / CVE-2026-87866. wolfSSL validates the real connection; curl then re-parses the same certificate and a manipulated validity length field makes it extract and match a different embedded key — pin authorization granted to a server that can't prove the pinned key. Two parsers reading one DER with different length handling.
  • GnuTLS builds: malicious WebSocket server reads memory past the send buffer — GHSA-4c9f-c4pg-phw4 / CVE-2026-107928. After a blocked send, gnutls_record_send() returns more bytes than it was given; curl's cursor follows the return value and sends adjacent memory. Out-of-bounds read → wire = memory disclosure to any malicious WS endpoint the client is coaxed into opening.
  • Hashed known_hosts: unrelated first entry turns a host-key mismatch into a reported missing key — GHSA-4cqc-m8hm-7c9j / CVE-2026-87865. Automation that trusts the CURLOPT_SSH_KEYFUNCTION callback's missing verdict to mean "first contact, accept-once" is handed a genuine mismatch shaped like a first contact.
  • curl CLI sets SSH host verification only for direct SFTP/SCP, not after a redirect — GHSA-4fmg-fm23-j6fc / CVE-2026-86410. A redirect chain into sftp:///scp:// reaches the host with host-key verification options never applied. Same gate-coverage shape as the aiohttp absolute-form leg on the Sept 15 parser page: the security option is set on the entry path, not the arrival path.
  • One oversized cookie line silently truncates all later cookies — GHSA-4hjw-pggv-qwfj / CVE-2026-92386. A server writes a jar record past the line-length parsing limit; every subsequent curl --cookie read of that jar silently aborts at that line, ignoring all following valid cookies for every domain.
  • One unloadable cookie deletes the whole jar — GHSA-cfhr-3c9j-cfhw / CVE-2026-86412. A cookie curl accepts, writes, then cannot reload makes the next run fail pre-connect, and cleanup replaces the jar with an empty file — cookies for unrelated domains destroyed.
  • HSTS extreme max-age truncates the cache and exits 0 — GHSA-53q4-87wj-266h / CVE-2026-87863. Cache save truncates the original file before writing a temp replacement; serialization failure deletes the temp; the error is silently ignored → empty/partial HSTS cache with a success exit code.
  • HSTS parent-before-child import order silently drops the child — GHSA-29c5-pmm5-3j3x / CVE-2026-87862. An includeSubDomains parent entry imported before a longer-lived child drops the child; when the parent expires, the child's valid policy is gone and curl issues plaintext HTTP where HTTPS was enforced.

E. Landing and protocol-injection legs

  • -J anti-clobber defeated by 103 Early Hints (or ETag ordering) → server-named local file overwrite — GHSA-g522-776c-cvvq / CVE-2026-92390. The documented non-overwrite protection is skipped when an intermediate 103 Early Hints response precedes the final response, or when ETag is processed before Content-Disposition under --etag-save — a server overwrites an existing local file named in Content-Disposition despite -J. Any scripted curl -J -O download pipeline (package fetchers, update scripts) is a server-controlled file-write primitive.
  • CURLOPT_CRLF turns an IMAP APPEND into client-side command injection — GHSA-mxp6-wxxv-r9rj / CVE-2026-87864. IMAP APPEND {N} advertises the raw input byte count while the transmitted payload is line-ending-expanded; the server consumes N bytes and executes the overflow as pipelined IMAP commands inside the authenticated session. Length computed over a different representation than the one sent — the count-vs-payload mismatch in the sending direction.
  • Tracked no-publish: malicious FTP/IMAP/POP3/SMTP server permanently omits the final control-response line to defeat transfer timeouts and block the whole multi-handle (CVE-2026-92387, DoS); deeply nested multipart via the public API stack-overflows the client (CVE-2026-92391, DoS).

Durable operator rules

  1. The client is an attack surface with the operator's identity on it. Recon automation, bug-bounty pipelines, CI fetch steps, and agent tool-calls run curl/libcurl with ambient Windows credentials (Negotiate), AWS SigV4 state, and persistent jar/HSTS files. A malicious target response can: mint a Kerberos ticket to attacker infrastructure (qqmr), hand Basic/Negotiate creds to a co-operated proxy (6qvf), write a chosen file via -J + 103 Early Hints (g522), or poison jar/HSTS state that outlives the run and silently degrades every later run (4hjw/cfhr/53q4/29c5). Standard owned-harness battery for the stack's curl build: CONNECT→401, userinfo redirect, 103 Early Hints + Content-Disposition, oversized cookie, unloadable cookie, extreme HSTS max-age.
  2. "Reuse key omits an identity dimension" is a four-for-one audit pattern. Client cert (4g5c), ambient Negotiate origin (34qg), interface binding (9644), and prior-auth TLS/FTP session state (533v) are the same bug class: the connection cache match function keys on host/port/scheme and ignores whatever else the connection authenticated as. Black-box probe: two lab transfers with two different values of one identity dimension to the same origin, then observe which value the second transfer's response reflects.
  3. TLS backend is a build artifact, not a version string — wolfSSL (wq9f), GnuTLS (4c9f), and Schannel (4g5c) legs exist only in specific builds. Same rule as the aiohttp pure-Python-parser leg and the Coraza engine-parity rule: fingerprint the backend (curl -V) before concluding a pinning or validation probe found nothing.
  4. Redirect-credential-strip audits must cover nonstandard transports. curl's CLI is the default fetch leg in most agent/recon tooling; the June 4 page's browser-library family now has its client-tool member. Version banding must come from the vendor advisory (GHSA fields are empty); treat "unknown severity" as unbanded, not low.
  5. Cache-file poisoning is a cross-run persistence primitive. Cookie-jar and HSTS-cache parsers fail open-silently (abort parsing / delete file / exit 0). Where a pipeline shares a jar/HSTS file across runs, one poisoned server response shapes every later request's credentials, scheme, and cookies — treat the shared state file as a target in its own right during authorized client-side engagements.

Same-wave folds (on existing pages)

  • GitHub Enterprise Server default-branch deletion → review-requirement bypass + attacker-controlled default content (GHSA-mj9w-xm4p-h2mp / CVE-2026-103620, GHES 3.18–3.22 fixed bands): a repo collaborator with write access could delete the default branch through the GraphQL API even when pull-request review was required, if branch deletion itself was unrestricted — the next branch push becomes the new default, and fresh clones plus default-branch API requests then serve attacker-controlled content. Folded below on the Sept 21 precedence page: controls enforced in one API surface (REST branch protection) must be re-probed in the sibling surface (GraphQL); "requires PR review" without "restrict who can delete branches" is a review bypass, not a safeguard.
  • Xerox/XERJ Console passkey-only requirement bypassed by bearer token → persistent successor credential minting (GHSA-vjpr-qxjc-7crv / CVE-2026-97406): an existing API bearer token could invoke the API-token creation endpoint even though login is passkey-only, minting long-lived successor credentials. Step-up/passkey gates enforced on the interactive path only; always replay lower-tier tokens against token-mint/credential-create routes. Same fold page.
  • Apache CouchDB _replicator leaks other users' replication credentials to any authenticated user (GHSA-5433-3876-mmp4 / CVE-2026-107755, ≤3.5.2): per-user filtering is absent on the system _replicator database, so a low-priv authenticated read pulls target-cluster credentials embedded in other users' replication docs. Any app backed by CouchDB: enumerate _replicator/_users/app-internal databases with the lowest real account before app-layer recon. Same fold page. (DoS leg CVE-2026-90799 chttpd binary-deser memory exhaustion tracked, not promoted.)

Tracked no-publish (21:31Z wave remainder)

X2000R/boa form-handler appliance pack (~25 critical unauth overflow/cmdi legs — single-endpoint firmware class per the Iskratel precedent; form-parameter fuzz map only), PEAK-System PCAN driver quintet (kernel memory-safety), Thunderbird quad (NTLM channel check, PIN dialog, AutoDiscover domain query, XMPP stanza attribute escaping — thin), War Thunder bearer token in cleartext first packet, EspoCRM PDF ImageSourceProvider ID authz bypass (vuldb-thin), Joomla lomart.fr UP plugin unauth code installation (Sept 26 re-enrichment, thin), Vert.x MySQL pre-auth multi-packet OOM (Oct 15 re-sync, DoS), eMudhra OneCRL block note (vendored-bundle shape already on the Oct 2 cert page), Tomcat/CouchDB/Plex/SiteGuard updated-feed sync of already-processed items. KEV unchanged (catalog 2026.10.20, 1754, cveID-set sha 1e235d71).

Sources