Jul 9, 2026·6 min read·21 visits
A missing ceiling on HTTP redirections in Micronaut's Netty HTTP Client allows a remote server to trap the client in an infinite loop, causing severe Denial of Service through thread and resource starvation.
The Netty-based HTTP Client in the Micronaut framework fails to enforce a maximum redirect ceiling by default when processing HTTP responses. This permits remote, attacker-controlled servers to trigger continuous, infinite redirect loops. The resulting recursion causes high CPU utilization, thread starvation, and potential memory exhaustion, inducing a Denial of Service (DoS) state in client-side applications.
The Micronaut HTTP Client is an asynchronous, reactive HTTP client built on top of the Netty event-driven network application framework. It is a core module in the Micronaut ecosystem, facilitating asynchronous service-to-service communication, metadata fetching, and API aggregation. By default, the client is configured to automatically follow HTTP 3xx redirection responses.
This vulnerability stems from a lack of state tracking in the client's redirection logic. Prior to the fix, the client parsed incoming Location headers and recursively initiated subsequent connections without keeping track of the total redirection depth. If a destination target resolves to a looping sequence, the client follows the route indefinitely.
Because the HTTP Client handles asynchronous, reactive streams via underlying Netty EventLoop groups, entering an endless redirect loop exhausts critical system resources. This attack surface is exposed whenever a Micronaut client fetches data from an endpoint controlled or influenced by an untrusted party, leading directly to a complete Denial of Service on the host application.
The root cause of GHSA-387m-935m-c4vw lies in the redirection resolution path of DefaultHttpClient and NettyHttpClient. When automatic redirect tracking is active (followRedirects = true), receiving an HTTP 3xx status code triggers the extraction of the target URI from the Location response header. The state machine then builds a secondary client request and subscribes to its response flow.
In vulnerable versions, the state machine did not keep any execution-context tracking or counter variables across these consecutive request hops. There was no boundary condition checking the accumulation of redirects. Consequently, when a loop occurs, the reactive pipeline continues to allocate execution frames, schedule channel operations, and spawn TCP sockets indefinitely.
This continuous execution sequence causes three distinct failure modes on the client host. First, the system experiences CPU exhaustion as the CPU cores dedicated to Netty's reactive event loops are driven to full capacity processing HTTP frames. Second, ephemeral port allocations and file descriptors are quickly consumed by active, unclosed connections. Lastly, the creation of sequential connection contexts and reactive stream subscribers puts high pressure on the JVM garbage collector, occasionally causing OutOfMemoryError states under concurrent conditions.
The vulnerability was mitigated across the Micronaut 3, 4, and 5 branches by adding a state-tracking attribute to the request lifecycle. The implementation adds a configuration property DEFAULT_MAX_REDIRECTS set to five, which represents the default ceiling for redirection paths. This value is configurable via the micronaut.http.client.max-redirects configuration namespace.
An attribute string micronaut.http.client.redirect-count was introduced to carry the current recursion level through the request execution context. During redirection, the client reads this value, verifies it against the configured threshold, increments it, and updates the subsequent request attributes.
Reviewing the official patch in the Netty client implementation demonstrates how this logic was integrated into the reactive flow:
// In DefaultHttpClient.java / NettyHttpClient.java
private static final String REDIRECT_COUNT = "micronaut.http.client.redirect-count";
// Redirection logic verification block:
int redirectCount = request.getAttribute(REDIRECT_COUNT, Integer.class).orElse(0) + 1;
if (redirectCount > configuration.getMaxRedirects()) {
return ExecutionFlow.error(decorate(new HttpClientException("Maximum number of redirects exceeded at redirect count: " + redirectCount)));
}
redirectRequest.setAttribute(REDIRECT_COUNT, redirectCount);If the integer counter exceeds the configured redirect ceiling, the execution flow is broken immediately by returning an HttpClientException wrapped in an error block. This immediately halts the reactive pipeline, preventing further network socket allocation and releasing event loop resources. The fix is considered structurally complete because it utilizes context-propagating request attributes, ensuring safety even in non-blocking, multi-threaded reactive execution paths.
Exploitation of GHSA-387m-935m-c4vw is straightforward and requires no prior credentials. The attack is feasible against any endpoint of a Micronaut application that accepts a user-defined URL and uses the default HTTP Client configuration to retrieve content from that URL. Common examples include metadata extractors, web scrapers, proxy components, and webhook handlers.
An attacker begins by deploying an HTTP server on a public domain. This malicious server is configured to return redirect headers pointing recursively to itself or another loop location. For instance, the server returns a 302 Found response with a Location: /loop header, where /loop subsequently redirects back to /loop.
When the victim Micronaut application processes the initial URL, it queries the attacker's server, parses the Location header, and automatically schedules another connection. Because there is no check on redirect depth, the client repeatedly generates requests. If an attacker submits several looping URLs concurrently, the client's entire pool of Netty execution threads is bound to the loop, causing the application to become unresponsive to legitimate client traffic.
The threat of this vulnerability is confined to availability, carrying a CVSS v3.1 base score of 7.5. Because the vulnerability only resides in the client execution flow, it does not allow for unauthorized access, data extraction, or remote privilege escalation. Confidentiality and Integrity are unaffected.
However, the availability impact is high. In systems running cloud microservice architectures, thread starvation inside one Micronaut application can quickly cascade. If the microservice hosts critical authentication middleware or acts as an API gateway, the resulting thread pool exhaustion can take down dependent systems.
Because the flaw consumes resources directly proportional to concurrent loops, it acts as an effective, low-complexity vector for Distributed Denial of Service (DDoS) amplification. An attacker only needs to send a single request containing a looping URL to initiate a long-lived resource exhaustion process on the victim application.
To fully remediate the issue, users must upgrade their Micronaut framework or HTTP Client dependencies to a patched version. For applications running on Micronaut 3, update to version 3.10.7 or higher. For Micronaut 4 applications, migrate to version 4.10.24 or higher, and for Micronaut 5 applications, update to version 5.0.1 or higher.
In circumstances where library upgrades cannot be immediately applied, developers can mitigate the risk by modifying the application's configuration file (application.yml). Setting the automatic redirection property to false prevents the client from following any redirects:
micronaut:
http:
client:
follow-redirects: falseIf automatic redirects are disabled, applications that require redirection support must implement manual location checking. By reading the Location header programmatically, the application can validate the target domain, verify that the URI matches a strict whitelist, and discard requests that exhibit cyclic behavior. Egress network filtering should also be applied to prevent microservices from communicating with untrusted external destinations.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
micronaut-http-client Micronaut | < 3.10.7 | 3.10.7 |
micronaut-http-client Micronaut | >= 4.0.0-M1, < 4.10.24 | 4.10.24 |
micronaut-http-client Micronaut | >= 5.0.0-M1, < 5.0.1 | 5.0.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-835 |
| Attack Vector | Network |
| CVSS v3.1 | 7.5 |
| Impact | Denial of Service (Availability: High) |
| Exploit Status | PoC Available |
| KEV Status | Not Listed |
The program contains an iteration or loop with an exit condition that cannot be reached or is not met, causing the program to loop indefinitely.
An unauthenticated remote denial of service vulnerability exists in the Unleash feature management platform. By submitting a crafted JSON payload containing deeply nested structures to an OpenAPI-validated endpoint, an attacker can trigger uncontrolled recursion within the error formatting module. This leads to a call-stack exhaustion (RangeError: Maximum call stack size exceeded) inside the Node.js runtime, causing the service to crash immediately without recovery.
CVE-2026-63004 is a server-side request forgery (SSRF) vulnerability in the Unleash feature management platform. Authenticated administrators with CREATE_ADDON or UPDATE_ADDON privileges can exploit this vulnerability to initiate requests to loopback addresses, private networks, and cloud metadata endpoints, potentially leading to information disclosure and credential extraction.
Prior to version 8.0.3, Unleash's Markdown event formatter directly mutated the global template-escaping function of the shared mustache Node.js module, resulting in a process-wide security degradation where HTML/Markdown escaping was permanently disabled for the application lifetime.
A critical SQL injection vulnerability exists in the GeoTools open-source Java library. This vulnerability is situated within the post-processing phase of OGC Filter conversion inside the PostGIS DataStore module. Specifically, the `jsonArrayContains` function does not validate or sanitize its arguments before constructing PostgreSQL SQL/JSON path evaluation queries. An unauthenticated remote attacker can exploit this weakness by submitting crafted filters via standard OGC services like WFS or WMS to execute arbitrary SQL commands on the underlying database system.
CVE-2026-61824 is a high-severity Cross-Site Scripting (XSS) vulnerability in kepano/defuddle before version 0.19.1. Custom site extractors for platforms such as X/Twitter, Substack, and YouTube constructed HTML representations via template string interpolation without output escaping. This allowed malicious pages to bypass standard parser sanitization routines and execute arbitrary JavaScript.
A high-severity vulnerability exists in KeystoneJS, a popular Node.js CMS and GraphQL framework, where the query resolution engine fails to validate signed negative integers within the pagination subsystem. Unauthenticated remote attackers can leverage this flaw to bypass the 'graphql.maxTake' safety boundary. By sending large negative values in the 'take' query parameter, the underlying Prisma ORM interprets the value as an instruction to fetch rows from the end of the collection, allowing malicious actors to bypass pagination limits, trigger database resource exhaustion, and execute application-level Denial of Service (DoS) attacks.