Bug 2536961 (CVE-2026-93568) - CVE-2026-93568 io.netty/netty-codec-http2: io.netty/netty-codec-http3: Netty: HTTP/2 and HTTP/3 Extended CONNECT requests are downgraded as regular CONNECT requests
Summary: CVE-2026-93568 io.netty/netty-codec-http2: io.netty/netty-codec-http3: Netty:...
Keywords:
Status: NEW
Alias: CVE-2026-93568
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
high
high
Target Milestone: ---
Assignee: Product Security
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2026-09-18 10:25 UTC by OSIDB Bzimport
Modified: 2026-09-18 20:00 UTC (History)
66 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed:
Embargoed:


Attachments (Terms of Use)

Description OSIDB Bzimport 2026-09-18 10:25:32 UTC
HTTP/2 and HTTP/3 Extended CONNECT requests are downgraded as regular CONNECT requests

A public GitHub Security Advisory (GHSA-w6j8-x45j-w75f) describes the following issue:

## Summary

Netty's HTTP/2 and HTTP/3 HTTP-object conversion paths collapse Extended CONNECT requests into ordinary HTTP/1.1 `CONNECT` requests.

An Extended CONNECT request such as:

```text
:method: CONNECT
:protocol: websocket
:scheme: https
:path: /admin/ws
:authority: ws.example:443
```

is converted to an HTTP/1.1 object shaped like:

```text
CONNECT ws.example:443 HTTP/1.1
host: ws.example:443
x-http2-scheme: https
```

or, for HTTP/3:

```text
CONNECT ws.example:443 HTTP/1.1
host: ws.example:443
x-http3-scheme: https
```

The converted request no longer carries the `:protocol` value or the Extended-CONNECT `:path`. A downstream handler using Netty's HTTP-object API therefore cannot distinguish this request from a regular CONNECT tunnel to `ws.example:443`.

That is a semantic security boundary. RFC 8441 defines Extended CONNECT as a different CONNECT mode: the `:protocol` pseudo-header selects the protocol for the stream, `:path` remains part of the target URI, and the server must not treat `:authority` as the host to tunnel to in the same way it would for a regular CONNECT request. RFC 9220 applies the same pseudo-header and setting semantics to HTTP/3.

## Technical Details

HTTP/2:

- `codec-http2/.../HttpConversionUtil.java:272-280` uses `:authority` as the HTTP/1 request URI for every `CONNECT` request.
- `codec-http2/.../HttpConversionUtil.java:328-337` creates a `DefaultHttpRequest` with that URI, then translates headers.
- `codec-http2/.../HttpConversionUtil.java:806-813` maps `:authority` to Host and `:scheme` to `x-http2-scheme`, but does not preserve request `:path`; unrecognized pseudo-headers such as `:protocol` are dropped.

HTTP/3:

- `codec-http3/.../Http3HeadersSink.java:79-94` recognizes Extended CONNECT and requires `:method`, `:scheme`, `:authority`, `:path`, and `:protocol`.
- `codec-http3/.../HttpConversionUtil.java:201-209` uses `:authority` as the HTTP/1 request URI for every `CONNECT` request.
- `codec-http3/.../HttpConversionUtil.java:259-268` creates a `DefaultHttpRequest` with that URI, then translates headers.
- `codec-http3/.../HttpConversionUtil.java:578-585` maps `:authority` to Host and `:scheme` to `x-http3-scheme`, but does not preserve request `:path`; `:protocol` is dropped as a pseudo-header.

The resulting object-level shape is security-relevant because applications and gateway integrations commonly authorize CONNECT differently from WebSocket, WebTransport, MASQUE, or other Extended CONNECT protocols. With Netty's conversion path, a policy that permits regular CONNECT to an allowlisted authority can be applied to an Extended CONNECT request whose actual protocol and path were erased before application code sees it.

## Impact

A remote HTTP/2 or HTTP/3 client can send an Extended CONNECT request that Netty presents to downstream HTTP-object handlers as a regular CONNECT tunnel.

In gateway, proxy, application-server, or protocol-bridging deployments that use Netty's HTTP-object conversion path, this can bypass routing or authorization logic that is meant to distinguish:

- regular CONNECT tunnels from WebSocket/WebTransport/MASQUE-style Extended CONNECT streams;
- allowed CONNECT authorities from protected Extended-CONNECT paths;
- enabled/registered Extended CONNECT protocols from ordinary CONNECT traffic.

This report does not claim memory corruption, code execution, confidentiality impact, or impact on applications that never route HTTP/2 or HTTP/3 requests through Netty's HTTP-object adapters. The demonstrated impact is integrity loss through protocol-state confusion before application policy runs.

## Suggested Fix

Recommended fix direction:

- do not convert Extended CONNECT into an ordinary HTTP/1 `CONNECT` object without preserving the Extended-CONNECT state;
- either reject Extended CONNECT in `HttpConversionUtil.toHttpRequest(...)` unless Netty can expose the state safely, or preserve it with explicit extension headers such as `x-http2-protocol` / `x-http3-protocol` and `x-http2-path` / `x-http3-path` for request conversion;
- keep regular CONNECT behavior unchanged;
- add regression tests covering direct conversion and the frame-to-object adapters for both HTTP/2 and HTTP/3;
- add controls proving regular CONNECT and Extended CONNECT no longer produce the same HTTP-object shape.

If maintainers prefer not to support Extended CONNECT through the HTTP-object API, the safest fix is to fail closed and require users to handle it at the native HTTP/2 or HTTP/3 frame/header layer.

## References

- Netty security policy: https://github.com/netty/netty/security/policy
- RFC 8441, Extended CONNECT: https://datatracker.ietf.org/doc/html/rfc8441#section-4
- RFC 9220, WebSockets over HTTP/3: https://datatracker.ietf.org/doc/html/rfc9220#section-3
- RFC 9113, HTTP/2 request pseudo-header fields: https://datatracker.ietf.org/doc/html/rfc9113#section-8.3.1
- RFC 9114, HTTP/3 request pseudo-header fields and CONNECT: https://datatracker.ietf.org/doc/html/rfc9114#section-4.3.1
- Go HTTP/2 Extended CONNECT implementation note requiring negotiation before use: https://go.dev/src/net/http/h2_bundle.go
- Go issue discussing Extended CONNECT API concerns: https://github.com/golang/go/issues/27244

## Affected Products

- `io.netty:netty-codec-http2`
- `io.netty:netty-codec-http3`

Confirmed affected:

- current `4.2` branch at `7bae566a93e69409697fe57fa807910ba5c9720e`
- `netty-4.2.15.Final` at `a41f7b289ce1d697c50846f3ade3983e22b2ed40`
- `netty-4.2.2.Final` at `660edeaefa` for HTTP/2
- `netty-4.2.0.Final` at `09e64d259c99` for HTTP/2
- `netty-4.1.135.Final` at `f05f765d81460799c53123a207f665bf3b465171` for HTTP/2

Suggested affected ranges:

- `io.netty:netty-codec-http2 >= 4.1.64.Final, <= 4.1.135.Final`
- `io.netty:netty-codec-http2 >= 4.2.0.Final, <= 4.2.15.Final`
- `io.netty:netty-codec-http3 >= 4.2.8.Final, <= 4.2.15.Final`

The HTTP/2 lower 

[truncated]

Affected:
- maven:io.netty:netty-codec-http2 affected >= 4.1.64.Final, <= 4.1.137.Final; fixed unknown
- maven:io.netty:netty-codec-http2 affected >= 4.2.0.Final, <= 4.2.17.Final; fixed unknown
- maven:io.netty:netty-codec-http3 affected >= 4.2.8.Final, <= 4.2.15.Final; fixed unknown

Fixed versions: see advisory

Advisory: https://github.com/netty/netty/security/advisories/GHSA-w6j8-x45j-w75f


Note You need to log in before you can comment on or make changes to this bug.