GHSA-fj9w-c36g-h5x8 CVE-2026-85716
AsyncHttpClient doesn't verify SCRAM and Digest mutual-authentication responses
- Severity
- 3.7 / 10
- Low · CVSS 3.1
- Exploit chance (EPSS)
- 0.41%
- Chance of exploitation in the next 30 days. Higher than 35.15% of scored vulnerabilities.
- Known exploited
- No
- Not in CISA's catalog
- Fix
3.0.12- Upgrade org.asynchttpclient:async-http-client to this version or later
Description
Impact
For SCRAM, and for Digest with mutual authentication, the client computes the server's verification value (the SCRAM ServerSignature, or the Digest rspauth) but does not act on the result. If the value is present and does not verify, the client only logs it and still delivers the response to the application as a successful, authenticated result. A server that never proved knowledge of the shared secret is accepted, so the client loses its ability to detect an impostor. Over TLS the real server always returns a valid value and the issue is inert; it matters over a non TLS transport, or when the transport is already compromised, where it removes the client's only signal that the peer does not know the secret.
Affected versions
- 3.x: 3.0.8 through 3.0.11
Earlier 3.0.x releases are not affected: neither SCRAM nor the Digest Authentication-Info handling existed before 3.0.8. The 2.x line is not affected either: it has no SCRAM support, and its interceptor chain does not implement Digest mutual authentication, so there is no verification result to act on.
Patches
Fixed in 3.0.12. A present ServerSignature (SCRAM) or rspauth (Digest) that does not verify now fails the request instead of being logged and ignored, on both the origin and proxy paths.
Known limitations
Verification is only enforced when the value is present and the parameters the client sent can be recovered. A response that omits the Authentication-Info header entirely, or that carries the header without a recognisable verification parameter, is still accepted: a well behaved server may send the value in chunked trailers, which the client does not read. An impostor that simply omits the value is therefore still accepted. The two schemes differ on malformed input: SCRAM aborts when the data parameter is present but is not valid base64, whereas Digest treats an unparseable rspauth (an unterminated quote, an empty unquoted value, or a bare rspauth token) as absent and accepts the response. Enforcing presence is tracked as a follow up.
Verification is also skipped when the parameters the client sent cannot be recovered from its own Authorization header, in which case the exchange is delivered rather than failed.
Details
In the auth interceptor, processScramAuthenticationInfo and processAuthenticationInfo computed the verification value and compared it, but did not stop the response from being delivered. Both now abort the exchange when the value is present and does not verify. The Digest expected value must be computed over the parameters actually sent on the wire, which the client recovers from its own Authorization header, because the realm carried on the response future is rebuilt for header emission and does not hold the values that were sent.
Note that 3.0.12 is itself affected by a separate issue, GHSA-rqf5-2wxv-rjf4, where a Digest challenge the client cannot read downgrades to Basic and sends the password in cleartext. Upgrade to 3.0.13 to pick up both fixes.
Known limitation
This fix does not cover Digest exchanges negotiated with qop="auth-int". Under auth-int the rspauth signs the response entity-body, which has not been read when the header is processed, so the expected value cannot be derived at that point. The client logs a warning and delivers the response without enforcing mutual authentication.
A peer that controls the challenge can select this deliberately by offering qop="auth-int" alone, which switches mutual authentication off for the whole exchange. Offering auth,auth-int does not work, because the client prefers auth. Verification under auth-int needs to be deferred until the body has been read, which is tracked separately as GHSA-qhv6-3pmh-95q4.
Affected versions
Maven
| Package | Vulnerable | Fixed in |
|---|---|---|
| org.asynchttpclient:async-http-client | >= 3.0.8, < 3.0.12 |
3.0.12 |
How to fix
Move to the fixed version or later with your package manager, update the lockfile, and run your tests. If the package only arrives through another dependency, upgrade that dependency first. If none of its releases pulls a fixed version yet, force the version with your package manager's override.
org.asynchttpclient:async-http-client Maven → 3.0.12
- maven
<dependency><groupId>org.asynchttpclient</groupId><artifactId>async-http-client</artifactId><version>3.0.12</version></dependency>- gradle
implementation("org.asynchttpclient:async-http-client:3.0.12")
Severity breakdown
CVSS 3.1 3.7
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N
- Attack vector
- Network
- Attack complexity
- High
- Privileges required
- None
- User interaction
- None
- Scope
- Unchanged
- Confidentiality
- None
- Integrity
- Low
- Availability
- None
Weakness
CWE-287: Improper Authentication
When an actor claims to have a given identity, the product does not prove or insufficiently proves that the claim is correct.
How to prevent it
- Architecture and Design: Use an authentication framework or library such as the OWASP ESAPI Authentication feature.
CWE-390: Detection of Error Condition Without Action
The product detects a specific error, but takes no actions to handle the error.
How to prevent it
- Implementation: Properly handle each exception. This is the recommended solution. Ensure that all exceptions are handled in such a way that you can be sure of the state of your system at any given moment.
- Implementation: If a function returns an error, it is important to either fix the problem and try again, alert the user that an error has happened and let the program continue, or alert the user and close and cleanup the program.
- Testing: Subject the product to extensive testing to discover some of the possible instances of where/how errors or return values are not handled. Consider testing techniques such as ad hoc, equivalence partitioning, robustness and fault tolerance, mutation, and fuzzing.
References
Packages
Other links
- github.com/AsyncHttpClient/async-http-client/security/advisories/GHSA-fj9w-c36g…
- github.com/AsyncHttpClient/async-http-client/pull/2235
- github.com/AsyncHttpClient/async-http-client/commit/10b3db9910f0bbad2ea3dc7c755…
- github.com/AsyncHttpClient/async-http-client/commit/685173afea07892462071d966ef…
- github.com/AsyncHttpClient/async-http-client/commit/7fe8700fd5b46c668cee7774624…
Timeline
- Published
- Last updated by the source
- Latest EPSS score
Related advisories
| Advisory | Severity | Why it's related |
|---|---|---|
| GHSA-p2jm-6hj6-9rjg AsyncHttpClient: Cookies received over plaintext HTTP can plant, overwrite or delete Secure cookies set over HTTPS | Medium | Also affects org.asynchttpclient:async-http-client |
| GHSA-3wp9-xfwm-rjjf AsyncHttpClient: WebSocket proxy credentials sent to the origin server over a CONNECT tunnel | Medium | Also affects org.asynchttpclient:async-http-client |
| GHSA-mfj3-87qq-382v AsyncHttpClient: Digest authentication cnonce generated with a non-cryptographic random source | Low | Also affects org.asynchttpclient:async-http-client |
| GHSA-jmqq-x5g9-9p2w AsyncHttpClient: Replay to a different host sends the original host request and credentials to the new host | Critical | Also affects org.asynchttpclient:async-http-client |
| GHSA-f9m8-cv68-674w AsyncHttpClient: Cookie Domain attribute is not checked against the public suffix list, so a cookie can be set for co.uk | Medium | Also affects org.asynchttpclient:async-http-client |
| GHSA-rqf5-2wxv-rjf4 AsyncHttpClient: Digest challenge without a usable nonce downgrades to Basic and sends the password in cleartext | High | Also affects org.asynchttpclient:async-http-client |
| GHSA-v2j5-22fr-j62r AsyncHttpClient: Pooled connections can still be shared across NTLM, Negotiate and proxy logins | High | Also affects org.asynchttpclient:async-http-client |
| GHSA-2jwh-9rmr-j4xf AsyncHttpClient CookieStore Silently Overrides Caller's Explicit Cookie Header via setHeader (Bypass of CVE-2024-53990 Fix) | Medium | Also affects org.asynchttpclient:async-http-client |
MergeHarbor checks every repository's dependencies against this database, ranks what matters by exploitability and reachability, routes it to the owning team and opens the fix pull request.
Check your repos with MergeHarbor