CVE-2023-34462 is a denial-of-service vulnerability in Netty where a specially crafted TLS ClientHello can trick the SniHandler into allocating up to 16MB of heap memory per connection, and enough such connections drive the JVM into an OutOfMemoryError. It was fixed in Netty 4.1.94.Final, carries a CVSS 3.1 base score of 6.5 (medium), and matters far more than that number suggests because Netty sits underneath a huge amount of Java infrastructure — gRPC, Reactor Netty, Elasticsearch clients, and many others.
The reason this is worth a close read is that most teams do not know they run Netty. It arrives transitively, and a medium-severity DoS in a component you did not know you had is exactly the kind of thing that surfaces during an incident rather than a planning meeting.
Root cause: trusting a length field during the handshake
When a TLS client connects, it sends a ClientHello message. If the server uses SNI (Server Name Indication) to pick a certificate — common for multi-tenant or virtual-host setups — Netty's SniHandler and its parent AbstractSniHandler parse that ClientHello to extract the requested hostname.
The flaw is that the handler reads a length value from the incoming record and allocates a ByteBuf to hold the message based on that value, without adequately bounding it against a sane maximum. A malicious client can advertise a large length, and the handler dutifully reserves up to 16MB of heap for that single connection before it ever validates the content.
One connection allocating 16MB is survivable. The attack is volumetric: open many connections, each sending a crafted ClientHello, and — especially when there is no idle timeout to reap half-open connections — the allocations stack up until the heap is exhausted and the process throws OutOfMemoryError. No valid TLS session is ever completed; the damage is done during the handshake.
Affected and fixed versions
The vulnerability affects Netty versions prior to 4.1.94.Final. The fix landed in 4.1.94.Final, which introduced a maxClientHelloLength parameter on the SniHandler and AbstractSniHandler constructors so the allocation can be capped.
Check what you actually run — remember this is almost always transitive:
# Maven: find every path that pulls in netty
mvn dependency:tree -Dincludes=io.netty:netty-handler
# Gradle
./gradlew dependencyInsight --dependency netty-handler
The package that carries the vulnerable code is netty-handler (the SNI classes live there), but Netty modules are versioned together, so bumping your Netty BOM covers it.
The fix
Upgrade Netty to 4.1.94.Final or later. If you consume Netty through the BOM, bump the BOM version and let it align every Netty module:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-bom</artifactId>
<version>4.1.94.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
If your Netty version is pinned by a framework — Spring Boot, gRPC-Java, Elasticsearch's client — the cleanest path is to upgrade that framework to a release that already depends on a patched Netty, rather than forcing an override that may not be tested against the rest of the framework.
After patching, if you construct SniHandler directly, set an explicit maxClientHelloLength to a value appropriate for your traffic rather than relying on the default.
Defense in depth for handshake DoS
Even patched, TLS handshake abuse is a category worth hardening against:
- Set connection idle timeouts. The absence of an idle timeout is what turns per-connection allocation into a sustained exhaustion attack. An
IdleStateHandlerthat closes stalled connections limits how many an attacker can hold open. - Cap concurrent connections per source at the load balancer or reverse proxy.
- Terminate TLS at a hardened edge (a managed load balancer or reverse proxy) where possible, so your application Netty instances are not directly exposed to arbitrary internet ClientHellos.
- Monitor heap and connection counts so a slow climb triggers an alert before an OOM.
These do not replace the upgrade, but they blunt the whole class of handshake-time resource attacks.
Why you probably do not know you run Netty
CVE-2023-34462 is a textbook transitive-dependency problem. Almost no one adds io.netty to their build file directly; it comes in under gRPC, Reactor, database drivers, or search clients. That means a manual audit of your top-level dependencies will not reveal your exposure at all.
This is where dependency resolution earns its keep. An SCA scanner walks the full tree, identifies the exact Netty version resolved in your build, and flags it against the affected range — including when three different frameworks each drag in their own Netty version. A platform such as Safeguard can then show which services across your estate resolve a vulnerable Netty so remediation is targeted rather than a blanket, risky bump everywhere. For the underlying mechanics, see our dependency scanner guide.
FAQ
Does CVE-2023-34462 require authentication to exploit?
The advisory describes it as exploitable by a remote authenticated attacker in some framing, but the practical exposure is any client that can complete the start of a TLS handshake with an SNI-enabled Netty server. Because the damage happens during the handshake, treat any internet-facing SNI listener on a vulnerable version as at risk and patch it.
What is the severity of this vulnerability?
It carries a CVSS 3.1 base score of 6.5 (medium). The impact is availability only — there is no data disclosure or code execution — but a successful attack can take a service down, which for many teams is a serious operational event.
I use gRPC / Spring / Elasticsearch. Am I affected?
Possibly, because all of those depend on Netty transitively. Run mvn dependency:tree -Dincludes=io.netty:netty-handler (or the Gradle equivalent) to see the resolved version. If it is below 4.1.94.Final, upgrade the framework to a release that bundles a patched Netty.
Is there a workaround if I cannot upgrade?
Setting connection idle timeouts and limiting concurrent connections per source materially reduces the risk, since the attack depends on holding many connections open simultaneously. This is a mitigation, not a fix — the 16MB per-handshake allocation is only truly bounded in 4.1.94.Final and later.