Skip to content

GHSA-fj9w-c36g-h5x8 CVE-2026-85716

AsyncHttpClient doesn't verify SCRAM and Digest mutual-authentication responses

Low Maven
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
Weakness
CWE-287 Improper Authentication
CWE-390 Detection of Error Condition Without Action
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

PackageVulnerableFixed 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

Timeline

  1. Published
  2. Last updated by the source
  3. Latest EPSS score
AdvisorySeverityWhy 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
Is this in your code?

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