REDHAT-BUG-2536962: Input Validation
HTTP/1 absolute-form Host mismatch is translated to HTTP/2 :authority, overriding the request-target authority
A public GitHub Security Advisory (GHSA-cg2g-fxr4-mg8m) describes the following issue:
Summary
HttpConversionUtil.toHttp2Headers(...) translates an HTTP/1 request with an absolute-form request-target and a conflicting Host header into HTTP/2 using the Host header as :authority.
For example, this raw HTTP/1 request:
http GET http://request-target.example/admin HTTP/1.1 Host: host-header.example
is translated by Netty into HTTP/2 control data with:
text :scheme = http :path = /admin :authority = host-header.example
The request-target authority request-target.example is discarded because Netty only takes the absolute-form request-line authority when the Host header is empty.
This creates a host/authority confusion primitive in Netty-based HTTP/1 to HTTP/2 proxy or gateway pipelines. A security decision made against the absolute-form request-target authority can be bypassed when Netty forwards the request over HTTP/2 using attacker-controlled Host as :authority.
Technical Details
In codec-http2/src/main/java/io/netty/handler/codec/http2/HttpConversionUtil.java, toHttp2Headers(...) initializes host from the HTTP/1 Host header:
java String host = inHeaders.getAsString(HttpHeaderNames.HOST);
For non-origin-form requests, it parses the request target and sets the HTTP/2 path:
java String requestTarget = request.uri(); out.path(toHttp2Path(requestTarget));
When the request-target has a scheme and authority, Netty parses the scheme/authority portion, but only uses that authority if Host was empty:
java URI requestTargetUri = URI.create(http2PathlessRequestTarget(requestTarget)); // Take from the request-line if HOST header was empty host = isNullOrEmpty(host) ? requestTargetUri.getAuthority() : host; setHttp2Scheme(inHeaders, requestTargetUri, out);
Finally, Netty emits :authority from host:
java setHttp2Authority(host, out);
The result is that a conflicting Host header overrides the authoritative absolute-form request-target authority during HTTP/1 to HTTP/2 conversion.
Impact
In a Netty-based proxy or gateway that accepts HTTP/1, performs access control, routing, tenant selection, egress allowlisting, or cache-keying based on the absolute-form request-target, and then forwards the request over HTTP/2 using HttpConversionUtil.toHttp2Headers(...), an attacker can send:
http GET http://allowed.example/admin HTTP/1.1 Host: blocked-or-attacker.example
The gateway can approve the request based on allowed.example, while Netty emits an HTTP/2 request with :authority=blocked-or-attacker.example.
This can bypass host or tenant security boundaries, poison cross-host cache entries, or route requests to an unintended upstream. The primitive is not a generic application Host-header trust issue; it is a protocol-conversion inconsistency inside Netty's HTTP/1 to HTTP/2 translation helper.
Suggested Fix
Recommended fix direction:
- If the HTTP/1 request-target is absolute-form and contains an authority component, construct HTTP/2 :authority from that request-target authority. - Alternatively, reject conversion when absolute-form request-target authority and Host differ after scheme-based normalization. - Preserve current origin-form behavior where Host is the authority source. - Add regression tests for mismatched absolute-form authority/Host, matching authority/Host, origin-form Host, userinfo stripping, IPv6 literals, and explicit ports.
Affected Package/Versions
Primary package: io.netty:netty-codec-http2
Related package: io.netty:netty-codec-http
Confirmed affected:
- current 4.2 branch at 7bae566a93e69409697fe57fa807910ba5c9720e - 4.2.15.Final at a41f7b289ce1d697c50846f3ade3983e22b2ed40 - 4.1.135.Final at f05f765d81460799c53123a207f665bf3b465171
Suggested affected ranges:
- >= 4.1.0.Final, <= 4.1.135.Final - >= 4.2.0.Final, <= 4.2.15.Final
References
- Netty security policy: https://github.com/netty/netty/security/policy - RFC 9112 request-target and absolute-form rules: https://datatracker.ietf.org/doc/html/rfc9112#section-3.2 - RFC 9113 request pseudo-header fields: https://datatracker.ietf.org/doc/html/rfc9113#section-8.3.1 - RFC 9110 http URI authority syntax: https://datatracker.ietf.org/doc/html/rfc9110#section-4.2.1 - HTTPWG mismatching absolute URI and Host discussion: https://github.com/httpwg/http-core/issues/191 - HTTPWG absolute-form precedence clarification: https://github.com/httpwg/http-core/issues/1105 - Netty HTTP/2 content-length request smuggling advisory: https://github.com/advisories/GHSA-f256-j965-7f32 - Netty HTTP/2 request-smuggling validation advisory: https://github.com/advisories/GHSA-wm47-8v5p-wjpj
CWE and CVSS
Primary CWE: CWE-444 (Inconsistent Interpretation of HTTP Requests).
Secondary CWE: CWE-20 (Improper Input Validation / protocol normalization).
Suggested CVSS v3.1:
text CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N
Suggested severity: High, score 8.1.
Rationale: a remote unauthenticated HTTP/1 client can trigger the conversion differential in a gateway/proxy deployment. The strongest impact is integrity: host, tenant, egress, or route policy can be checked against one authority and forwarded over HTTP/2 to another. Availability impact is not claimed.
Duplicate Boundary
Adjacent public Netty advisories cover different surfaces:
- GHSA-f256-j965-7f32 / CVE-2021-21409: HTTP/2 request smuggling due content-length validation. - GHSA-wm47-8v5p-wjpj / CVE-2021-21295: HTTP/2 request smuggling due missing validation. - GHSA-c7h2-758g-pf5v: private triage item for HTTP/2 :path HTAB surviving HTTP/1 downgrade.
This candidate is HTTP/1 absolute-form to HTTP/2 :authority translation. It does not rely on content-length ambiguity, HTTP/2-to-HTTP/1 downgrade, or request-line whitespace.
Local PoV
PoV file in the local bundle:
po
[truncated]
Affected: - maven:io.netty:netty-codec-http2 affected >= 4.1.0.Final, <= 4.1.137.Final; fixed unknown - maven:io.netty:netty-codec-http2 affected >= 4.2.0.Final, <= 4.2.17.Final; fixed unknown
Fixed versions: see advisory
Advisory: https://github.com/netty/netty/security/advisories/GHSA-cg2g-fxr4-mg8m
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
io.netty:netty-codec-http2to a version that resolves this vulnerability.Fixed in 4.1.135.Final - Upgrade
Upgrade
io.netty:netty-codec-http2to a version that resolves this vulnerability.Fixed in 4.2.15.Final - Upgrade
Upgrade
io.netty:netty-codec-http2to a version that resolves this vulnerability.Patch GHSA-f256-j965-7f32 - Upgrade
Upgrade
io.netty:netty-codec-http2to a version that resolves this vulnerability.Patch GHSA-wm47-8v5p-wjpj - Upgrade
Upgrade
io.netty:netty-codec-http2to a version that resolves this vulnerability.Patch GHSA-cg2g-fxr4-mg8m
Event History
Frequently Asked Questions
Which deployments are exposed to this issue?
Netty-based HTTP/1 to HTTP/2 proxy or gateway pipelines are exposed when they make a security decision using the authority in an absolute-form HTTP/1 request target and then forward the request as HTTP/2.
What does an attacker need to send to exploit the confusion?
The attacker needs to send an HTTP/1 absolute-form request whose request-target authority conflicts with its Host header. During conversion, a non-empty Host header becomes the HTTP/2 :authority value while the request-target authority is discarded.
How can this lead to a security-control bypass?
A proxy or gateway may evaluate the request-target authority, such as an allowed host, but Netty can forward the request with the attacker-controlled Host value as HTTP/2 :authority. This allows the authority used for the security decision to differ from the authority received by the downstream HTTP/2 service.