Where
-Infinity
0
Severity
9.8
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

Vulnerability

Micronaut's HTTP client is vulnerable to "HTTP Request Header Injection" due to not validating request headers passed to the client.

Example of vulnerable code:

java @Controller("/hello") public class HelloController {

@Inject @Client("/") RxHttpClient client;

@Get("/external-exploit") @Produces(MediaType.TEXTPLAIN) public String externalExploit(@QueryValue("header-value") String headerValue) { return client.toBlocking().retrieve( HttpRequest.GET("/hello") .header("Test", headerValue) ); } }

In the above case a query value received from a user is passed as a header value to the client. Since the client doesn't validate the header value the request headers and body have the potential to be manipulated.

For example, a user that supplies the following payload, can force the client to make multiple attacker-controlled HTTP requests.

java List<String> headerData = List.of( "Connection: Keep-Alive", // This keeps the connection open so another request can be stuffed in. "", "", "POST /hello/super-secret HTTP/1.1", "Host: 127.0.0.1", "Content-Length: 31", "", "{\"new\":\"json\",\"content\":\"here\"}", "", "" ); String headerValue = "H\r\n" + String.join("\r\n", headerData);; URI theURI = UriBuilder .of("/hello/external-exploit") .queryParam("header-value", headerValue) // Automatically URL encodes data .build(); HttpRequest<String> request = HttpRequest.GET(theURI); String body = client.toBlocking().retrieve(request);

Note that using @HeaderValue instead of @QueryValue is not vulnerable since Micronaut's HTTP server does validate the headers passed to the server, so the exploit can only be triggered by using user data that is not an HTTP header (query values, form data etc.).

Impact

The attacker is able to control the entirety of the HTTP body for their custom requests. As such, this vulnerability enables attackers to perform a variant of Server Side Request Forgery.

Patches

The problem has been patched in the micronaut-http-client versions 1.2.11 and 1.3.2 and above.

Workarounds

Do not pass user data directly received from HTTP request parameters as headers in the HTTP client.

References

Fix commits - https://github.com/micronaut-projects/micronaut-core/commit/9d1eff5c8df1d6cda1fe00ef046729b2a6abe7f1 - https://github.com/micronaut-projects/micronaut-core/commit/6deb60b75517f80c57b42d935f07955c773b766d - https://github.com/micronaut-projects/micronaut-core/commit/bc855e439c4a5ced3d83195bb59d0679cbd95add

For more information

If you have any questions or comments about this advisory:

Open an issue in micronaut-core Email us at info@micronaut.io

Credit

Originally reported by @JLLeitschuh

1 / 2
First published (updated )
Severity
8.2
EPSS
0.22%
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

In JsonBeanPropertyBinder::expandArrayToThreshold in io.micronaut:micronaut-json-core before Micronaut 4 4.10.16 and in Micronaut 3 before 3.10.5 does not correctly handle descending array index order during form-urlencoded body binding, which allows remote attackers to cause a denial of service (non-terminating loop, CPU exhaustion, and OutOfMemoryError) via crafted indexed form parameters (e.g., authors[1].name followed by authors[0].name).

Example

With such an application

java package dosform;

import io.micronaut.http.HttpResponse; import io.micronaut.http.MediaType; import io.micronaut.http.annotation.Body; import io.micronaut.http.annotation.Consumes; import io.micronaut.http.annotation.Controller; import io.micronaut.http.annotation.Get; import io.micronaut.http.annotation.Post; import io.micronaut.http.annotation.Produces;

import java.net.URI;

@Controller class HomeController {

@Produces(MediaType.TEXTHTML) @Get String index() { return """ <!DOCTYPE html> <html> <head> <title></title> </head> <body> <form action="/submit" method="post"> <label for="firstAuthor">Fist Author</label> <input id="firstAuthor" name="authors[0].name" type="text"/>

<label for="secondAuthor">Second Author</label> <input id="secondAuthor" name="authors[1].name" type="text"/> <label for="thirdAuthor">Third Author</label> <input id="thirdAuthor" name="authors[2].name" type="text"/>

<button type="submit">Submit</button> </form> </body> </html> """; }

@Consumes(MediaType.APPLICATIONFORMURLENCODED) @Post("/submit") HttpResponse<?> submit(@Body Book book) { return HttpResponse.seeOther(URI.create("/")); } } package dosform;

import io.micronaut.core.annotation.Introspected;

import java.util.Objects;

@Introspected public class Author { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; }

@Override public final boolean equals(Object o) { if (!(o instanceof Author)) return false;

Author author = (Author) o; return Objects.equals(name, author.name); }

@Override public int hashCode() { return Objects.hashCode(name); }

@Override public String toString() { return "Author{" + "name='" + name + '\'' + '}'; } } package dosform;

import io.micronaut.core.annotation.Introspected;

import java.util.List; import java.util.Objects;

@Introspected public class Book { private List<Author> authors; public List<Author> getAuthors() { return authors; } public void setAuthors(List<Author> authors) { this.authors = authors; }

@Override public final boolean equals(Object o) { if (!(o instanceof Book)) return false;

Book book = (Book) o; return Objects.equals(authors, book.authors); }

@Override public int hashCode() { return Objects.hashCode(authors); }

@Override public String toString() { return "Book{" + "authors=" + authors + '}'; } }

Sending curl -v -X POST 'http://127.0.0.1:8080/submit' -H 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'authors[1].name=RobertGalbraith' --data-urlencode 'authors[0].name=JKRowling' causes sustained CPU usage and unbounded memory growth (eventually OutOfMemoryError).

Patches For Micronaut 4, the problem has been patched in micronaut-core, dependencies with group id io.micronaut, since 4.10.16.

For Micronaut 3, the problem has been patched since 3.10.5

Users upgrade to the latest version of the framework.

Workarounds There is no way for users to fix or remediate the vulnerability without upgrading.

References PR Fix: https://github.com/micronaut-projects/micronaut-core/pull/12410

1 / 2
Source: GitHub
First published (updated )
Severity
7.8
EPSS
0.04%
AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:L

Summary Enabled but unsecured management endpoints are susceptible to drive-by localhost attacks. While not typical of a production application, these attacks may have more impact on a development environment where such endpoints may be flipped on without much thought.

Details A malicious/compromised website can make HTTP requests to localhost. Normally, such requests would trigger a CORS preflight check which would prevent the request; however, some requests are "simple" and do not require a preflight check. These endpoints, if enabled and not secured, are vulnerable to being triggered.

Impact Production environments typically disable unused endpoints and secure/restrict access to needed endpoints. A more likely victim is the developer in their local development host, who has enabled endpoints without security for the sake of easing development.

1 / 2
Source: GitHub
First published (updated )
Severity
7.5
EPSS
0.10%
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

DefaultHtmlErrorResponseBodyProvider in io.micronaut:micronaut-http-server since 4.7.0 and until 4.10.7 used an unbounded ConcurrentHashMap cache with no eviction policy. If the application throws an exception whose message may be influenced by an attacker, for example, including request query value parameters, this could be used by remote attackers to cause a denial of service (unbounded heap growth and OutOfMemoryError).

Fixed via: https://github.com/micronaut-projects/micronaut-core/commit/1e2ba2c14386af3d47751732d02053a72b0b49b3

1 / 2
Source: GitHub
First published (updated )

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203