async-http-client: Cookie header not stripped on cross-origin redirect
Summary
async-http-client leaks Cookie headers to cross-origin redirect targets. When following a redirect across a security boundary (different origin, or HTTPS→HTTP downgrade), the propagatedHeaders() method in Redirect30xInterceptor.java strips Authorization and Proxy-Authorization headers but does not strip Cookie, so session cookies and other sensitive cookie values are forwarded to the redirect target — which may be attacker-controlled.
Details
The vulnerability is in client/src/main/java/org/asynchttpclient/netty/handler/intercept/Redirect30xInterceptor.java.
The caller computes stripAuth on each redirect:
boolean sameBase = request.getUri().isSameBase(newUri);
boolean stripAuth = !sameBase || schemeDowngrade || stripAuthorizationOnRedirect;
// ...
requestBuilder.setHeaders(propagatedHeaders(request, realm, keepBody, stripAuth));
stripAuth is true whenever the redirect crosses an origin, downgrades the scheme, or the caller opted in via AsyncHttpClientConfig#isStripAuthorizationOnRedirect().
In the vulnerable version, propagatedHeaders() only removes Authorization and Proxy-Authorization in that branch — Cookie is left untouched:
private static HttpHeaders propagatedHeaders(Request request, Realm realm, boolean keepBody, boolean stripAuthorization) {
HttpHeaders headers = request.getHeaders()
.remove(HOST)
.remove(CONTENT_LENGTH);
if (!keepBody) {
headers.remove(CONTENT_TYPE);
}
if (stripAuthorization || (realm != null && (realm.getScheme() == AuthScheme.NTLM
|| realm.getScheme() == AuthScheme.SCRAM_SHA_256))) {
headers.remove(AUTHORIZATION)
.remove(PROXY_AUTHORIZATION);
// BUG: COOKIE is not removed here, so cookies leak across the security boundary.
}
return headers;
}
The companion test class RedirectCredentialSecurityTest covers Authorization / Proxy-Authorization stripping on cross-origin redirects and scheme downgrades, but has no coverage for Cookie, which is why the regression went unnoticed.
Proof of concept
import org.asynchttpclient.*;
AsyncHttpClient client = asyncHttpClient();
// trusted-api.com responds 302 -> https://evil.com
Request request = new RequestBuilder("GET")
.setUrl("https://trusted-api.com/endpoint")
.setHeader("Cookie", "session=abc123; csrf=xyz789; api_key=secret")
.setHeader("Authorization", "Bearer token123")
.build();
client.executeRequest(request).get();
// Request seen by evil.com after the redirect:
// Authorization: <stripped>
// Cookie: session=abc123; csrf=xyz789; api_key=secret <-- leaked
Impact
- Session hijacking — leaked session cookies allow impersonation.
- CSRF token theft — CSRF tokens carried in cookies are disclosed.
- API key theft — API keys stored in cookies are disclosed.
- Privacy — tracking identifiers leak to third-party origins.
Realistic attack paths:
- Open-redirect in a trusted API endpoint.
- Compromised CDN or API gateway injecting redirects.
- MITM on a plaintext hop in the redirect chain.
Fix
Add COOKIE to the headers removed alongside AUTHORIZATION / PROXY_AUTHORIZATION on the security-boundary branch:
if (stripAuthorization) {
headers.remove(AUTHORIZATION)
.remove(PROXY_AUTHORIZATION)
.remove(COOKIE);
} else if (realm != null && (realm.getScheme() == AuthScheme.NTLM
|| realm.getScheme() == AuthScheme.SCRAM_SHA_256)) {
headers.remove(AUTHORIZATION)
.remove(PROXY_AUTHORIZATION);
}
Note that the URI-scoped CookieStore will re-add any cookies that legitimately match the new target after propagatedHeaders returns, so legitimate cross-origin sessions tracked by the client are not broken.
Fixed in 3.0.10 and 2.15.0 by commit 3b0e3e9e.
Czego dotyczy
Kliknij technologię, aby zobaczyć wszystkie dotyczące jej podatności.
| Platforma | Paczka | Podatne wersje | Poprawka w wersji |
|---|---|---|---|
| Java / Kotlin (Maven) | org.asynchttpclient:async-http-client | >= 3.0.0.Beta1, < 3.0.10, >= 2.0.0, < 2.15.0 | 3.0.10, 2.15.0 |
Odnośniki
- https://github.com/AsyncHttpClient/async-http-client/security/advisories/GHSA-fmxf-pm6p-7xgm
- https://nvd.nist.gov/vuln/detail/CVE-2026-45300
- https://github.com/AsyncHttpClient/async-http-client/commit/3b0e3e9e
- https://github.com/AsyncHttpClient/async-http-client
- https://github.com/AsyncHttpClient/async-http-client/releases/tag/async-http-client-project-3.0.10
- Wektor CVSS
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N- Słabość (CWE)
CWE-200- Platforma
- Java / Kotlin (Maven)
- Paczka
org.asynchttpclient:async-http-client- Ujawniono
- 18.05.2026
- Aktualizacja
- 11.10.2026 13:20
Źródła i licencje
OSV / GitHub Advisory Database - GHSA-fmxf-pm6p-7xgm - CC BY 4.0
Historia podatności: org.asynchttpclient:async-http-client
Wszystkie opisane podatności tej paczki (Java / Kotlin (Maven)), od najnowszej. Widać, czy to jednorazowa wpadka, czy paczka, której trzeba pilnować.
- Wszystkich wpisów
- 18
- Pierwsza → ostatnia
- 10.2018 10.2026
- Bez poprawki
- 0
- Wykorzystywana w atakach
- 0
Rozkład istotności
- Krytyczna 2
- Wysoka 6
- Średnia 8
- Niska 2
Ujawnienia w latach
- 2018: 1
- 2019: 0
- 2020: 0
- 2021: 0
- 2022: 0
- 2023: 0
- 2024: 1
- 2025: 0
- 2026: 16
-
async-http-client: Cookie header not stripped on cross-origin redirect ten wpis
Dowiedz się, które podatności dotyczą Twojej aplikacji
Po podłączeniu integracji DockRay i włączeniu raportowania oprogramowania DockRay porównuje zgłoszone wersje komponentów ze znanymi podatnościami i powiadamia o potwierdzonych dopasowaniach. Zakres zależy od obsługiwanej technologii i dostępnych biuletynów.