{"id":"GHSA-v2j5-22fr-j62r","summary":"AsyncHttpClient: Pooled connections can still be shared across NTLM, Negotiate and proxy logins","details":"### Impact\nThe 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.\n\n1. **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.\n2. **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.\n3. **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.\n\n### Who is Impacted\nApplications 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.\n\n### Affected versions\n* 3.x: 3.0.13\n* 2.x: 2.16.1\n\nEarlier versions are covered by GHSA-vvp4-63h8-v5pm.\n\n### Patches\nFixed 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.\n\nThe 2.x line is end of life and will not receive a fix. Upgrade to 3.0.14.\n\n### Workarounds\nUse 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.\n\nIncomplete fix of GHSA-vvp4-63h8-v5pm.","aliases":["CVE-2026-107230"],"modified":"2026-10-08T17:01:03.329024369Z","published":"2026-10-08T16:49:46Z","database_specific":{"github_reviewed_at":"2026-10-08T16:49:46Z","nvd_published_at":"2026-10-07T22:17:03Z","cwe_ids":["CWE-346","CWE-863"],"severity":"HIGH","github_reviewed":true},"references":[{"type":"WEB","url":"https://github.com/AsyncHttpClient/async-http-client/security/advisories/GHSA-v2j5-22fr-j62r"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-107230"},{"type":"WEB","url":"https://github.com/AsyncHttpClient/async-http-client/commit/d3bb4d68b41acf5d3ab7541afa9fdfe7ec3ba054"},{"type":"PACKAGE","url":"https://github.com/AsyncHttpClient/async-http-client"},{"type":"WEB","url":"https://github.com/AsyncHttpClient/async-http-client/releases/tag/async-http-client-project-3.0.14"}],"affected":[{"package":{"name":"org.asynchttpclient:async-http-client","ecosystem":"Maven","purl":"pkg:maven/org.asynchttpclient/async-http-client"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"3.0.0"},{"fixed":"3.0.14"}]}],"versions":["3.0.0","3.0.1","3.0.10","3.0.11","3.0.12","3.0.13","3.0.2","3.0.3","3.0.4","3.0.5","3.0.6","3.0.7","3.0.8","3.0.9"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-v2j5-22fr-j62r/GHSA-v2j5-22fr-j62r.json"}},{"package":{"name":"org.asynchttpclient:async-http-client","ecosystem":"Maven","purl":"pkg:maven/org.asynchttpclient/async-http-client"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"2.0.0"},{"last_affected":"2.16.1"}]}],"versions":["2.0.0","2.0.1","2.0.10","2.0.11","2.0.12","2.0.13","2.0.14","2.0.15","2.0.16","2.0.17","2.0.18","2.0.19","2.0.2","2.0.20","2.0.21","2.0.22","2.0.23","2.0.24","2.0.25","2.0.26","2.0.27","2.0.28","2.0.29","2.0.3","2.0.30","2.0.31","2.0.32","2.0.33","2.0.34","2.0.35","2.0.36","2.0.37","2.0.38","2.0.39","2.0.4","2.0.40","2.0.5","2.0.6","2.0.7","2.0.8","2.0.9","2.1.0","2.1.0-RC1","2.1.0-RC2","2.1.0-RC3","2.1.0-RC4","2.1.0-alpha1","2.1.0-alpha10","2.1.0-alpha11","2.1.0-alpha12","2.1.0-alpha13","2.1.0-alpha14","2.1.0-alpha15","2.1.0-alpha16","2.1.0-alpha17","2.1.0-alpha18","2.1.0-alpha19","2.1.0-alpha2","2.1.0-alpha20","2.1.0-alpha21","2.1.0-alpha22","2.1.0-alpha23","2.1.0-alpha24","2.1.0-alpha25","2.1.0-alpha26","2.1.0-alpha3","2.1.0-alpha4","2.1.0-alpha5","2.1.0-alpha6","2.1.0-alpha7","2.1.0-alpha8","2.1.0-alpha9","2.1.1","2.1.2","2.10.0","2.10.1","2.10.2","2.10.3","2.10.4","2.10.5","2.11.0","2.12.0","2.12.1","2.12.2","2.12.3","2.12.4","2.14.5","2.15.0","2.16.0","2.16.1","2.2.0","2.2.1","2.3.0","2.4.0","2.4.1","2.4.2","2.4.3","2.4.4","2.4.5","2.4.6","2.4.7","2.4.8","2.4.9","2.5.0","2.5.1","2.5.2","2.5.3","2.5.4","2.6.0","2.7.0","2.8.0","2.8.1","2.9.0"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-v2j5-22fr-j62r/GHSA-v2j5-22fr-j62r.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N"}]}