CVE-2026-107231: AsyncHttpClient Digest Challenge Without A Usable Vulnerability

HIGH
Advisory Identifier: GHSA-rqf5-2wxv-rjf4
CWE-319 CWE-757 CWE-522
Published
Advisory Summary

CVE-2026-107231 is a HIGH digest challenge without a usable vulnerability (CWE-319: Cleartext Transmission of Sensitive Information) affecting AsyncHttpClient libraries in the Maven ecosystem. The issue involves digest challenge without a usable nonce downgrades to basic and sends the password in cleartext. Remediation is available by upgrading affected packages to version 3.0.13, 2.16.1.

CVE-2026-107231 at a Glance

CVE Identifier CVE-2026-107231
GHSA Identifier GHSA-rqf5-2wxv-rjf4
Severity HIGH
CVSS v3.1 Base Score N/A
CWE Classification CWE-319: Cleartext Transmission of Sensitive Information
Affected Product AsyncHttpClient
Package Ecosystem Maven
Published Date
Last Updated

How to Fix CVE-2026-107231

To remediate this vulnerability, upgrade all affected AsyncHttpClient dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

org.asynchttpclient:async-http-client fixed: 3.0.13
<dependency>
    <groupId>org.asynchttpclient</groupId>
    <artifactId>async-http-client</artifactId>
    <version>3.0.13</version>
</dependency>
org.asynchttpclient:async-http-client fixed: 2.16.1
<dependency>
    <groupId>org.asynchttpclient</groupId>
    <artifactId>async-http-client</artifactId>
    <version>2.16.1</version>
</dependency>
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

mvn dependency:tree -Dincludes=org.asynchttpclient

How to Check if You Are Affected

To determine whether your Java application is affected by CVE-2026-107231, inspect your build dependencies using the Maven Dependency Plugin:

mvn dependency:tree -Dincludes=org.asynchttpclient

Analyze the terminal output to locate any version of AsyncHttpClient in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 3.0.13), your application is affected.

Note: The mvn dependency:tree -Dincludes=org.asynchttpclient command inspects the resolved dependency graph declared in your project's POM files; it does not perform automated security scanning or inspect runtime dynamic classpaths. Always verify runtime container classpaths and shaded JARs.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-319: Cleartext Transmission of Sensitive Information, where the product transmits sensitive or security-critical data in cleartext in a communication channel that can be sniffed by unauthorized actors. In AsyncHttpClient, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

### Impact A Digest challenge that does not yield a usable nonce is treated as a Basic challenge. The client then answers it with `Authorization: Basic`, which carries the username and password base64 encoded and so recoverable by anyone who sees the request. Any of these is enough, sent by whoever writes the 401 or 407: ``` WWW-Authenticate: Digest realm="protected" WWW-Authenticate: Digest realm="protected", nonce="" ``` The challenge announces itself as Digest, so it passes the check that would otherwise reject a non-Digest challenge for a Digest realm. It then fails to produce a nonce, and the absence of a nonce is what selected Basic. A server offering plain `Basic` to a Digest realm gets nothing, so labelling the challenge Digest and leaving the nonce out is what makes the difference. This is reachable by anyone who can write the challenge: a malicious or compromised origin, a proxy, or an attacker on a plaintext hop. Digest exists precisely to keep the password off those hops. A server that stores only HA1, and anyone impersonating the real origin, does not otherwise learn the password itself, so the disclosure enables reuse against other services. Both the target and the proxy paths are affected, through `parseWWWAuthenticateHeader` and `parseProxyAuthenticateHeader`. ### Affected versions * 3.x: up to and including 3.0.12 * 2.x: up to and including 2.16.0 This is long-standing behaviour on both lines, not a recent regression. On 3.0.12 there is one additional way to reach it: a quoted parameter ending in an unescaped backslash, such as `realm="C:\"`, makes the closing quote read as escaped so the nonce is never found. That trigger is specific to 3.0.12. The downgrade it led to is fixed, but the nonce is still lost on such a challenge: every conformant reader treats the closing quote as escaped. The exchange now fails instead of falling back to Basic. ### Patches Fixed in 3.0.13 on the 3.x line and in 2.16.1 on the 2.x line. The scheme now comes from the challenge itself instead of being inferred from whether a nonce was found, so a Digest challenge stays Digest even when it cannot be read. With no nonce it produces no Authorization header at all, which fails the exchange rather than downgrading it. The 3.x fix also corrects quoted-pair handling so that a backslash before any character other than a quote or another backslash is kept as written, matching Apache HttpComponents. That repairs a 3.0.12 regression where an unescaped realm such as `DOMAIN\Users` was corrupted to `DOMAINUsers` and failed every digest comparison. This is a deliberate deviation from a strict reading of RFC 9110 Section 5.6.4, under which a backslash before any character is a quoted-pair. Reading it strictly is what corrupts the unescaped spelling that servers actually send, and the decoding is not reversible either way, so the client follows the same rule as Apache HttpComponents. ### Workarounds No configuration prevents this. Until you can upgrade, do not use Digest authentication against a server you do not control, and do not use it over plaintext HTTP. ### Details `Realm.Builder.parseWWWAuthenticateHeader` and `parseProxyAuthenticateHeader` selected the scheme with `isNonEmpty(nonce) ? AuthScheme.DIGEST : AuthScheme.BASIC`, so any challenge that produced no nonce became a Basic challenge and `Unauthorized401Interceptor` resent the request using `computeBasicAuthentication`.

CVE-2026-107231 Affected AsyncHttpClient Versions

2 component(s)
Fixed Versions:
3.0.132.16.1
Product / Package Ecosystem Affected Versions Fixed Version
org.asynchttpclient:async-http-client
Maven
≥ 3.0.0.Beta1
< 3.0.13
3.0.13
org.asynchttpclient:async-http-client
Maven
≥ 2.0.0
< 2.16.1
2.16.1

References

Frequently Asked Questions

What is CVE-2026-107231?
CVE-2026-107231 is a security vulnerability in AsyncHttpClient involving Digest challenge without a usable nonce downgrades to Basic and sends the password in cleartext under CWE-319: Cleartext Transmission of Sensitive Information.
Which AsyncHttpClient versions are affected?
Affected versions include releases prior to 3.0.13, 2.16.1 across affected packages: org.asynchttpclient:async-http-client.
What version fixes CVE-2026-107231?
Upgrading to 3.0.13, 2.16.1 (or the latest patched release for your respective branch) resolves the vulnerability.
Is async-http-client affected?
Yes, org.asynchttpclient:async-http-client is affected in releases prior to 3.0.13, 2.16.1. Upgrade your dependency to 3.0.13, 2.16.1 or later.
What CWE is associated with CVE-2026-107231?
CVE-2026-107231 is classified under CWE-319: Cleartext Transmission of Sensitive Information (The product transmits sensitive or security-critical data in cleartext in a communication channel that can be sniffed by unauthorized actors.).
How can I check Maven dependencies for CVE-2026-107231?
Run the dependency tree command: 'mvn dependency:tree -Dincludes=org.asynchttpclient'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-rqf5-2wxv-rjf4",
  "modified" : "2026-10-08T16:23:36Z",
  "published" : "2026-10-08T16:23:36Z",
  "aliases" : [ "CVE-2026-107231" ],
  "summary" : "AsyncHttpClient: Digest challenge without a usable nonce downgrades to Basic and sends the password in cleartext",
  "details" : "### Impact\nA Digest challenge that does not yield a usable nonce is treated as a Basic challenge. The client then answers it with `Authorization: Basic`, which carries the username and password base64 encoded and so recoverable by anyone who sees the request.\n\nAny of these is enough, sent by whoever writes the 401 or 407:\n\n```\nWWW-Authenticate: Digest realm=\"protected\"\nWWW-Authenticate: Digest realm=\"protected\", nonce=\"\"\n```\n\nThe challenge announces itself as Digest, so it passes the check that would otherwise reject a non-Digest challenge for a Digest realm. It then fails to produce a nonce, and the absence of a nonce is what selected Basic. A server offering plain `Basic` to a Digest realm gets nothing, so labelling the challenge Digest and leaving the nonce out is what makes the difference.\n\nThis is reachable by anyone who can write the challenge: a malicious or compromised origin, a proxy, or an attacker on a plaintext hop. Digest exists precisely to keep the password off those hops. A server that stores only HA1, and anyone impersonating the real origin, does not otherwise learn the password itself, so the disclosure enables reuse against other services.\n\nBoth the target and the proxy paths are affected, through `parseWWWAuthenticateHeader` and `parseProxyAuthenticateHeader`.\n\n### Affected versions\n* 3.x: up to and including 3.0.12\n* 2.x: up to and including 2.16.0\n\nThis is long-standing behaviour on both lines, not a recent regression. On 3.0.12 there is one additional way to reach it: a quoted parameter ending in an unescaped backslash, such as `realm=\"C:\\\"`, makes the closing quote read as escaped so the nonce is never found. That trigger is specific to 3.0.12. The downgrade it led to is fixed, but the nonce is still lost on such a challenge: every conformant reader treats the closing quote as escaped. The exchange now fails instead of falling back to Basic.\n\n### Patches\nFixed in 3.0.13 on the 3.x line and in 2.16.1 on the 2.x line. The scheme now comes from the challenge itself instead of being inferred from whether a nonce was found, so a Digest challenge stays Digest even when it cannot be read. With no nonce it produces no Authorization header at all, which fails the exchange rather than downgrading it.\n\nThe 3.x fix also corrects quoted-pair handling so that a backslash before any character other than a quote or another backslash is kept as written, matching Apache HttpComponents. That repairs a 3.0.12 regression where an unescaped realm such as `DOMAIN\\Users` was corrupted to `DOMAINUsers` and failed every digest comparison. This is a deliberate deviation from a strict reading of RFC 9110 Section 5.6.4, under which a backslash before any character is a quoted-pair. Reading it strictly is what corrupts the unescaped spelling that servers actually send, and the decoding is not reversible either way, so the client follows the same rule as Apache HttpComponents.\n\n### Workarounds\nNo configuration prevents this. Until you can upgrade, do not use Digest authentication against a server you do not control, and do not use it over plaintext HTTP.\n\n### Details\n`Realm.Builder.parseWWWAuthenticateHeader` and `parseProxyAuthenticateHeader` selected the scheme with `isNonEmpty(nonce) ? AuthScheme.DIGEST : AuthScheme.BASIC`, so any challenge that produced no nonce became a Basic challenge and `Unauthorized401Interceptor` resent the request using `computeBasicAuthentication`.",
  "severity" : [ {
    "type" : "CVSS_V4",
    "score" : "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "Maven",
      "name" : "org.asynchttpclient:async-http-client"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "3.0.0.Beta1"
      }, {
        "fixed" : "3.0.13"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "<= 3.0.12"
    }
  }, {
    "package" : {
      "ecosystem" : "Maven",
      "name" : "org.asynchttpclient:async-http-client"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "2.0.0"
      }, {
        "fixed" : "2.16.1"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "<= 2.16.0"
    }
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/AsyncHttpClient/async-http-client/security/advisories/GHSA-rqf5-2wxv-rjf4"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-107231"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/AsyncHttpClient/async-http-client/commit/8376866aa9b5a7653ad19db9d472692f875caa83"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/AsyncHttpClient/async-http-client/commit/c8d639bf6ac341d377d610a93570bcd15565f1a6"
  }, {
    "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-2.16.1"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/AsyncHttpClient/async-http-client/releases/tag/async-http-client-project-3.0.13"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-319", "CWE-522", "CWE-757" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-10-08T16:23:36Z",
    "nvd_published_at" : "2026-10-07T22:17:03Z"
  }
}