Where
-Infinity
0
Severity
3.7
AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N

The AsyncHttpClient (AHC) library allows Java applications to easily execute HTTP requests and asynchronously process HTTP responses. Prior to 3.0.12 and 2.16.1, WebSocketHandler.upgrade aborts a handshake whose Sec-WebSocket-Accept value is missing or invalid but continues into pipeline installation and onOpen delivery. Frames coalesced with the invalid 101 response can be decoded and delivered from a peer that did not prove the handshake, although the request future fails and the channel closes. This issue is fixed in versions 3.0.12 and 2.16.1.

First published (updated )
Severity
9.4
CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:N/SC:H/SI:H/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Impact When a request is replayed onto a different host, the client updates only the current request and leaves the target request pointing at the original host. Four consumers read that stale value, and each one sends the first host's request, credentials, or both to the second host.

A replay happens through documented, ordinary features: a ResponseFilter that returns a different request, which is the supported failover pattern, and the IOException retry path. The attacker does not need to induce the replay; an application that uses failover produces it by design.

The socket to host B is filed in the connection pool under host A's key. A later request the application addresses to A is served over the connection to B, and A's Authorization header goes to B. Over a CONNECT tunnel, the client tunnels to B and negotiates TLS with B correctly, then writes A's request into that tunnel. B receives A's path, A's Host, and A's Authorization. TLS does not protect against this, because the handshake really is with B, so no certificate mismatch occurs. The replay reuses the original realm, so A's credentials are regenerated onto a replay request that carries no realm of its own. The cross-origin redirect path strips realms for exactly this reason; the replay path never did. The stale value also decides whether TLS is used at all. When the original request was http:// and the replay is https://, no SSL handler is installed and the replayed request, credentials included, is written in cleartext.

Affected versions 3.x: up to and including 3.0.12 2.x: up to and including 2.16.0

Both lines are affected identically. This is long-standing behaviour, not a recent regression.

Patches Fixed in 3.0.13 on the 3.x line and in 2.16.1 on the 2.x line. The target request now moves when a request is replayed, and the proxy moves with it: the proxy is part of the connection pool key, so correcting only the host would convert a harmless pool miss into a hit and route a proxied connection to a direct request.

Workarounds Do not use a ResponseFilter that replays to a different host, and disable request retries, if the client is configured with credentials or used through a proxy. Replaying to the same host is not affected.

Details NettyRequestSender.newNettyRequestAndResponseFuture calls setCurrentRequest without setTargetRequest, and replayRequest does not move the target either. The stale target is then read by the pool key derivation in NettyResponseFuture, by ConnectSuccessInterceptor when it writes the tunnelled request, by the realm selection in NettyRequestSender, and by NettyConnectListener when it decides whether to install an SSL handler.

Existing replay tests do not cover this, because all of them replay to the same host.

1 / 2
Source: GitHub
First published (updated )
Severity
8.8
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:H/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

The AsyncHttpClient (AHC) library allows Java applications to easily execute HTTP requests and asynchronously process HTTP responses. In 3.0.12, a peer offering only Digest qop=auth-int causes mutual-authentication verification to be skipped. AuthenticatorUtils.computeExpectedRspAuth returns no expected value for auth-int, and Interceptors treats that result as unverifiable but nonfatal, so a response with an invalid rspauth value is accepted. A peer that does not know the shared secret can therefore be accepted as the authenticated server. This issue is fixed in version 3.0.13.

First published (updated )
Severity
7.5
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

The AsyncHttpClient (AHC) library allows Java applications to easily execute HTTP requests and asynchronously process HTTP responses. Prior to 3.0.12 on 3.x and 2.16.1 on 2.x, the client infers that an HTTP proxy tunnel exists from the last request method rather than the CONNECT result. After a proxy rejects CONNECT, redirect or authentication handlers can write an origin request and its Authorization credentials onto the still-plaintext proxy connection. Basic credentials can be recovered directly, while NTLM responses may be cracked or relayed. This issue is fixed in versions 3.0.12 and 2.16.1.

First published (updated )
Severity
7.4
AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N

Impact The fix for GHSA-vvp4-63h8-v5pm in 3.0.13 folded the authenticated principal into the HTTP/1.1 connection pool key, so that a connection one principal authenticated with NTLM, Kerberos or SPNEGO is not handed to another. It left three cases out. In each, a socket that one identity authenticated can still be drawn by a request belonging to a different identity, and the server serves that request as the first one.

1. A login with no configured principal. Kerberos and SPNEGO against the ticket cache or the default JAAS login, which is the usual deployment, leave the realm's principal unset, and the key stayed unscoped in that case. A request to the same host that carries no credentials at all draws the authenticated socket and is served as the service identity. 2. The proxy realm. Only the origin realm went into the key. A connection authenticated to a proxy with NTLM or Negotiate is handed to requests of another proxy identity, or of none, and the proxy acts for them as the first identity. 3. Identities that share a user name. Only the principal string went into the key, so CORP\alice and OTHER\alice shared connections, as did two realms differing only in password, login context, keytab or service principal. The Kerberos login cache in SpnegoEngine had the same collision, and it was an unsynchronised map, so concurrent first use could hand one caller's login to another.

Who is Impacted Applications that authenticate with NTLM, Kerberos or SPNEGO, to an origin or to a proxy, and send requests under different identities, or both with and without credentials, to the same host through one client. The sharpest case is a service that calls an internal host under its own Kerberos identity and also fetches user-supplied URLs: a URL on that host is fetched as the service. Basic and Digest are not affected.

Affected versions 3.x: 3.0.13 2.x: 2.16.1

Earlier versions are covered by GHSA-vvp4-63h8-v5pm.

Patches Fixed in 3.0.14. The pool key now carries a digest of every field of the realm that decides which identity the connection ends up as, for the origin and the proxy separately, and a realm that authenticates the connection is scoped whether or not it names a principal. SpnegoEngine caches logins in a concurrent map keyed by every other field of that identity, and replaces a cached login when the password changes.

The 2.x line is end of life and will not receive a fix. Upgrade to 3.0.14.

Workarounds Use a separate AsyncHttpClient instance per identity, and do not share one between authenticated and unauthenticated requests to a host that uses NTLM or Negotiate. Disabling connection pooling also removes the reuse.

Incomplete fix of GHSA-vvp4-63h8-v5pm.

1 / 2
Source: GitHub
First published (updated )
Severity
4
AV:N/AC:H/PR:N/UI:N/S:C/C:N/I:L/A:N

The AsyncHttpClient (AHC) library allows Java applications to easily execute HTTP requests and asynchronously process HTTP responses. From 2.16.0 until 3.0.14, ThreadSafeCookieStore incompletely validates cookie Domain attributes. Missing private-section and default public-suffix rules, absent A-label normalization, locale-sensitive lowercasing, public-suffix host-only handling, and numeric or IP host checks allow one origin to store a cookie later sent to another origin. Applications sharing one client across trust domains can therefore receive attacker-injected cookies and may be exposed to session fixation. This issue is fixed in version 3.0.14.

First published (updated )
Severity
7.5
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Impact

With WebSocket compression enabled, the client inflates permessage-deflate messages with no limit on the decompressed size. It installed Netty's shared WebSocketClientCompressionHandler.INSTANCE, whose inflater is unbounded, and webSocketMaxFrameSize and webSocketMaxBufferSize only bound the compressed bytes, because the frame aggregator sits in front of the inflater.

A malicious or compromised WebSocket server, or anyone on the path of a ws:// connection, can therefore send a message of about 2 MiB that inflates to about 2 GiB, the most a Netty buffer can hold. The client then copies the inflated message again to hand it to the listener. That exhausts the heap of a typically sized JVM. Netty catches the resulting OutOfMemoryError and closes that connection, but while the buffer is live any other allocation in the process can fail too, and a server that keeps sending such messages, on one connection or several, keeps the client at heap exhaustion.

Who is Impacted

Only applications that enable WebSocket compression with setEnablewebSocketCompression(true), which is off by default, and connect to a WebSocket server that is untrusted, compromised, or reached over cleartext ws://.

Affected versions

3.x: up to and including 3.0.13 2.x: from 2.2.0, when WebSocket compression was added, up to and including 2.16.1

Patches

Fixed in 3.0.14. A new setting, webSocketMaxDecompressedFrameSize (setWebSocketMaxDecompressedFrameSize, or the org.asynchttpclient.webSocketMaxDecompressedFrameSize property), bounds how far a message may inflate, and a message that would go past it fails the connection. It defaults to 128000000 bytes, the same as webSocketMaxBufferSize, so a message is bounded alike whether or not it was compressed; a compressed message that inflates past that, which was accepted before, now fails the connection. With aggregateWebSocketFrameFragments turned off, the bound applies to each frame instead, and fragments are delivered one at a time. Set it lower if you enable compression and do not expect large messages. 0 disables the limit.

The 2.x line is end of life and will not receive a fix. Upgrade to 3.0.14.

Workarounds

Leave WebSocket compression disabled, which is the default.

Details

After the handshake the inbound pipeline is ws-decoder, ws-aggregator, PerMessageDeflateDecoder, ahc-ws: the aggregator, which enforces webSocketMaxBufferSize, sees each message before it is inflated. WebSocketClientCompressionHandler.INSTANCE is built with maxAllocation = 0, which Netty treats as unbounded, and Netty has deprecated it in favour of a constructor that takes a limit. RFC 6455 Section 10.4 asks an implementation to limit the size of a message after reassembly, and under RFC 7692 Section 6.2 the message delivered to the application is the decompressed payload.

This is a different path from the HTTP response decompression fixed under CVE-2026-85721, which never reached the WebSocket pipeline.

Attribution

AI-assisted tools were used to support discovery and analysis.

1 / 2
Source: GitHub
First published (updated )
Severity
7.5
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

The AsyncHttpClient (AHC) library allows Java applications to easily execute HTTP requests and asynchronously process HTTP responses. From 2.1.0 until 2.16.1 and 3.0.12, requests using an authenticated SOCKS proxy can expose the proxy's credentials to the origin because NettyRequestFactory and NettyRequestSender attach Proxy-Authorization without confirming that the request is being sent to an HTTP proxy. With preemptive proxy authentication, the header is attached to a plaintext HTTP request, exposing credentials such as directly reversible Basic credentials to the origin. With the default non-preemptive flow, a hostile origin can return a 407 response and ProxyUnauthorized407Interceptor sends the proxy credentials through the existing SOCKS tunnel, including NTLM, Kerberos, and SPNEGO credentials. Releases before 2.1.0 lack SOCKS proxy support. This issue is fixed in versions 2.16.1 and 3.0.12.

First published (updated )
Severity
4
CSRF, SSRF
AV:N/AC:H/PR:N/UI:N/S:C/C:N/I:L/A:N

Impact A cookie tossing / cookie injection issue (CWE-1275). ThreadSafeCookieStore stored a cookie under the value of its Domain attribute without verifying that the responding host is allowed to set a cookie for that domain (RFC 6265 §5.3 step 6). A host the client connects to can therefore plant a cookie scoped to an unrelated domain, and the client will then send that cookie on later requests to that domain.

Who is Impacted Applications that use a single AsyncHttpClient instance - and thus the default, shared CookieStore - to reach both an attacker-influenced host and a trusted host. Typical exposure: crawlers, link-preview / webhook fetchers, SSRF-style "fetch this URL" features, multi-backend aggregators, or following redirects to an attacker-controlled host. The attacker can write a cookie the client presents to the victim host (session fixation, overwriting a session id / CSRF-token cookie); they cannot read the victim host's cookies. Applications that talk only to a fixed trusted backend, or that disable/scope the cookie store, are not exposed.

Patches Fixed in 3.0.11 and 2.16.0

Workarounds - Disable the cookie store (setCookieStore(null)) when cookies are not needed; or - Use a separate AsyncHttpClient (separate cookie store) per trust domain so an attacker-influenced host and a trusted host never share a jar - Supply a custom CookieStore whose add(Uri, Cookie) rejects cookies whose Domain is not domain-matched by the request host.

1 / 2
Source: GitHub
First published (updated )

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203