ZeroPath at Black Hat USA 2026

Brief Summary: Netty SNI Handler Pre-Allocation DoS (CVE-2026-45416) Turns Nine Bytes Into 16 MiB of Memory Pressure

A short review of CVE-2026-45416, a high severity denial of service vulnerability in Netty's SNI handler where a crafted TLS ClientHello with as few as nine bytes triggers a 16 MiB memory allocation due to disabled default length guards.

CVE Analysis

8 min read

ZeroPath CVE Analysis
ZeroPath CVE Analysis

2026-06-12

Brief Summary: Netty SNI Handler Pre-Allocation DoS (CVE-2026-45416) Turns Nine Bytes Into 16 MiB of Memory Pressure
Experimental AI-Generated Content

This CVE analysis is an experimental publication that is completely AI-generated. The content may contain errors or inaccuracies and is subject to change as more information becomes available. We are continuously refining our process.

If you have feedback, questions, or notice any errors, please reach out to us.

[email protected]

Introduction

As few as nine bytes sent over a TCP connection can force a Netty based server to allocate 16 MiB of unpooled direct memory, and the default SNI handler configuration does nothing to stop it. CVE-2026-45416 exposes a denial of service condition in Netty's SslClientHelloHandler where a crafted TLS ClientHello message exploits a disabled length guard to trigger massive memory pre-allocation, retained until the attacker's connection closes.

Netty is the foundational asynchronous network I/O framework for the Java ecosystem, underpinning infrastructure components like Spring Boot, gRPC, Cassandra drivers, and Elasticsearch clients. With roughly 35,000 GitHub stars and adopters including Airbnb and Apple, a vulnerability in Netty's TLS handling has a broad blast radius across the industry.

Technical Information

Root Cause

The vulnerability lives in SslClientHelloHandler.decode() within the io.netty:netty-handler package. When a TLS ClientHello message arrives, the method reads the 24 bit handshake length field from the TLS record header. If the ClientHello does not fit entirely within the first TLS record, the code at line 161 eagerly allocates a buffer sized to the declared handshake length:

ctx.alloc().buffer(handshakeLength)

The intended safety mechanism is a guard at line 140:

handshakeLength > maxClientHelloLength && maxClientHelloLength != 0

This guard is supposed to reject oversized ClientHello messages. However, the three most commonly used constructors for SNI handling all pass maxClientHelloLength=0 and handshakeTimeoutMillis=0:

ConstructormaxClientHelloLengthhandshakeTimeoutMillis
SniHandler(Mapping)00
SniHandler(AsyncMapping)00
AbstractSniHandler()00

When maxClientHelloLength is 0, the condition maxClientHelloLength != 0 evaluates to false, causing the entire guard to short circuit regardless of the handshakeLength value. The handshakeTimeoutMillis=0 setting simultaneously prevents any timeout from being scheduled, so there is no mechanism to reclaim the buffer if the handshake stalls.

This is a textbook instance of CWE-770 (Allocation of Resources Without Limits or Throttling): an untrusted network input (the 24 bit handshake length field) is used directly as the allocation size with no effective upper bound.

Attack Flow

  1. Connection establishment: The attacker opens a TCP connection to a Netty based service that terminates TLS using one of the default SNI handler constructors.

  2. Crafted ClientHello: The attacker sends a TLS record containing a ClientHello with the 24 bit handshake length field set to 16,777,215 (0xFFFFFF), the maximum value. Only the TLS record header and the length field need to be present; the actual ClientHello payload can be minimal or absent. This requires as few as nine bytes.

  3. Guard bypass: The decode() method reads the handshake length. The guard at line 140 evaluates 16777215 > 0 && 0 != 0, which resolves to true && false, resulting in false. The guard does not trigger.

  4. Memory allocation: The code proceeds to line 161 and calls ctx.alloc().buffer(16777215). Because 16 MiB exceeds Netty's default pooled chunk size, this becomes an unpooled (direct memory) allocation performed immediately on the hot path.

  5. Buffer retention: The allocated buffer is retained in the handler, waiting for the rest of the ClientHello data that will never arrive. Because handshakeTimeoutMillis is 0, no timeout is scheduled to clean up the allocation.

  6. Amplification: The attacker repeats this across many connections. Each connection consumes approximately 16 MiB of direct memory. The amplification factor is approximately 1.86 million to one (9 bytes in, 16 MiB allocated).

  7. Service disruption: The accumulated memory pressure leads to OutOfMemoryError, container OOM kills, or severe performance degradation, resulting in denial of service.

The CVSS v3.1 vector AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H (score 7.5) reflects the network exploitability, low complexity, absence of authentication requirements, and high availability impact.

Why This Is Subtle

The initial bytes of the attack look like a legitimate TLS ClientHello. Standard network monitoring tools that inspect TLS traffic at the protocol level may not flag the oversized length field as anomalous, since the TLS specification permits large handshake messages. The vulnerability is not in the TLS protocol itself but in how Netty handles the allocation before validating the full message.

Additionally, the memory consumed is off heap direct memory, not JVM heap memory. Standard JVM heap monitoring and garbage collection metrics will not reflect the growing memory pressure. Operators need to monitor direct memory usage specifically (e.g., via java.nio.BufferPoolMXBean) to detect this condition.

Affected Systems and Versions

The vulnerability affects the io.netty:netty-handler package in two version branches:

BranchVulnerable VersionsFixed Version
4.1.xAll versions prior to 4.1.135.Final4.1.135.Final
4.2.x4.2.0.Final through 4.2.14.Final4.2.15.Final

The vulnerable configuration specifically requires use of the default SNI handler constructors: SniHandler(Mapping), SniHandler(AsyncMapping), or AbstractSniHandler(). These constructors pass maxClientHelloLength=0, which disables the length guard. Custom configurations that explicitly set a nonzero maxClientHelloLength may be partially protected, though upgrading remains the recommended action.

Because Netty is frequently included as a transitive dependency, organizations should audit their dependency trees using tools like Maven's dependency:tree or Gradle's dependencies task to identify all paths that resolve to a vulnerable version of io.netty:netty-handler.

Vendor Security History

Netty has experienced a concentrated period of security disclosures. The Cybersecurity Help security bulletin SB2026060813 cataloged 22 vulnerabilities published around the same timeframe as CVE-2026-45416. Notable recent CVEs include:

CVETypeSeverity
CVE-2026-45416SNI handler memory pre-allocation DoSHigh (7.5)
CVE-2026-44248MQTT Decoder DoSReported
CVE-2026-42578DoS in netty-handlerReported
CVE-2026-33871DoS vulnerabilityReported
CVE-2025-25193DoS (up to 4.1.118.Final)Reported
GHSA-389x-839f-4rhxDoS via environment file on WindowsReported

A pattern emerges across these disclosures: denial of service flaws in protocol decoders where Netty reads untrusted length fields from network input and allocates resources without effective bounds. Organizations that depend on Netty should plan for batch patching across multiple CVEs rather than addressing them individually, and should consider auditing other resource allocation paths in the framework for similar patterns.

The Netty project maintains public security advisories through the GitHub Security Advisory system and follows responsible disclosure practices. The CVE-2026-45416 advisory was published by maintainer chrisvest on June 5, 2026.

References

Detect & fix
what others miss

Works with
  • GitHub
  • GitLab
  • Bitbucket
  • Azure DevOps Services
  • Jira
  • Linear
  • Slack
  • Security Compass
Security magnifying glass visualization