CVE
CVE-2026-44891, CVE-2026-55831, CVE-2026-55833
CWE
CWE-400, CWE-770
Affected Surface
- Maven consumers of `io.netty:netty-codec-stomp` on Netty `4.1.x` before `4.1.136.Final` or `4.2.x` before `4.2.16.Final` that expose STOMP endpoints using `StompSubframeDecoder`
- Maven consumers of `io.netty:netty-codec-http` on Netty `4.1.x` before `4.1.136.Final` or `4.2.x` before `4.2.16.Final` that still include `SpdyFrameCodec` in reachable pipelines
- Java frameworks, gateways, and custom protocol services that pull affected Netty modules transitively rather than depending on them directly
The most relevant new package vulnerability cluster from the last three days sits in a dependency many Java teams do not review closely enough: Netty. NVD published two new SPDY issues on 20 July and one STOMP issue on 17 July, all fixed in the same Netty train: 4.1.136.Final and 4.2.16.Final. The common theme is not memory corruption. It is attacker-controlled resource growth inside protocol decoders that are easy to underestimate because they live in transport plumbing rather than business logic.
For AppSec teams, the important nuance is module reachability. CVE-2026-44891 is in io.netty:netty-codec-stomp. CVE-2026-55831 and CVE-2026-55833 are in io.netty:netty-codec-http, because Netty’s SPDY implementation lives there via SpdyFrameCodec. If your framework imports Netty transitively, you may be carrying reachable decoders without ever depending on them explicitly in your own pom.xml.
Affected Maven coordinates
| CVE | Maven package | Reachable class / path | Fixed in |
|---|---|---|---|
CVE-2026-44891 | io.netty:netty-codec-stomp | io.netty.handler.codec.stomp.StompSubframeDecoder | 4.1.136.Final, 4.2.16.Final |
CVE-2026-55831 | io.netty:netty-codec-http | SpdyFrameCodec.decode() -> DefaultSpdySettingsFrame | 4.1.136.Final, 4.2.16.Final |
CVE-2026-55833 | io.netty:netty-codec-http | SpdyFrameCodec zlib header decode path after maxHeaderSize truncation | 4.1.136.Final, 4.2.16.Final |
The release notes for both 4.1.136.Final and 4.2.16.Final strongly recommend upgrading specifically for these security fixes. Teams should read that as a coordinated train, not as three isolated CVEs that can be patched piecemeal.
CVE-2026-44891: STOMP header count was effectively unbounded
The clearest issue in the set is CVE-2026-44891. Netty’s advisory says StompSubframeDecoder limited the length of individual header lines with maxLineLength, but did not limit the total number of headers or their cumulative size. In other words, a decoder guard existed, but it guarded the wrong dimension.
The published proof-of-concept is refreshingly direct. The server side is only a few lines:
ChannelFuture serverFuture = new ServerBootstrap()
.group(group)
.channel(NioServerSocketChannel.class)
.childHandler(new StompSubframeDecoder())
.bind(8080)
.sync();
And the client side shows how cheap the attack is:
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
sb.append("a:1\n");
}
byte[] bulkHeaders = sb.toString().getBytes(StandardCharsets.UTF_8);
for (int i = 1; i <= 50_000; i++) {
out.write(bulkHeaders);
}
This is the kind of PoC AppSec teams should pay attention to because it does not rely on exotic protocol abuse. The malicious input is just a huge number of short, individually valid headers. Netty accumulates them into DefaultStompHeadersSubframe until the JVM throws OutOfMemoryError.
CVE-2026-55831: one SPDY SETTINGS frame could materialize 262,144 map entries
The first SPDY issue, CVE-2026-55831, is a stronger example of protocol-to-heap amplification. Netty’s advisory says SpdyFrameCodec.decode() accepted a peer-declared SETTINGS entry count up to the 24-bit frame-length limit and forwarded each entry into DefaultSpdySettingsFrame, which uses a TreeMap.
The published PoC fingerprint tells the story better than a CVSS paragraph:
NETTY_SPDY_SETTINGS_COUNT_MAP_TRIGGERED
settings_count=262144
wire_bytes=2097164
approx_heap_delta=17692272
That means roughly 2 MiB of attacker-controlled wire data caused Netty to materialize 262,144 entries and about 17-18 MiB of heap growth, plus ordered-map insertion cost. The advisory’s core implementation concern is worth remembering: the decoder validated that the payload length matched the declared entry count, but it did not impose an implementation-level count budget between “frame is syntactically valid” and “insert every setting into a map.”
This is exactly the kind of bug that slips past teams who equate protocol validity with resource safety.
CVE-2026-55833: SPDY zlib inflation continued after the size guard had already fired
The second SPDY issue, CVE-2026-55833, is more subtle. Netty had already decided the raw header parser exceeded maxHeaderSize and marked the frame truncated, but the zlib-backed decode path still kept inflating attacker-controlled data and skipping over the expanded bytes.
Netty’s own advisory gives a compact PoC fingerprint:
NETTY_SPDY_ZLIB_DECODED_AFTER_LIMIT_TRIGGERED
compressed_bytes=12253
declared_name_length=12582912
max_header_size=16
truncated=true
invalid=false
Those values matter:
- only
12,253compressed bytes are needed on the wire, - the inflated header-name length reaches
12 MiB, maxHeaderSize=16had already been exceeded,- yet the decoder still burned CPU and allocation work on the expanded data.
In practice, the guard became an observation rather than a stop condition. That is why the issue is better understood as compression amplification inside the decoder rather than as a normal oversize-header rejection.
Why these three CVEs belong together
All three fixes are denial-of-service issues, but they exercise three different decoder anti-patterns:
- unbounded accumulation of individually valid fields (
CVE-2026-44891); - trusting attacker-declared collection cardinality (
CVE-2026-55831); - continuing expensive decode work after a size limit is already known to have been exceeded (
CVE-2026-55833).
That grouping matters for code review. These are not “legacy protocol oddities” in the abstract. They are examples of how parser correctness and parser safety diverge. A protocol decoder can accept well-formed input and still hand an attacker a clean resource-exhaustion primitive.
Scoping your exposure
Start by determining whether the vulnerable modules are present at all:
mvn dependency:tree -Dincludes=io.netty:netty-codec-stomp,io.netty:netty-codec-http
./gradlew dependencies --configuration runtimeClasspath | \
rg "io\\.netty:(netty-codec-stomp|netty-codec-http)"
Then search for the specific code paths that make the CVEs reachable:
rg -n "StompSubframeDecoder|DefaultStompHeadersSubframe" src
rg -n "SpdyFrameCodec|DefaultSpdySettingsFrame|readSettingsFrame|readSetting" src
If you do not find these classes in your own source, do not stop. Netty is commonly buried inside higher-level frameworks and custom gateways. Inspect the runtime dependency tree, not just the application source tree.
The SPDY issues deserve an extra reality check because many teams believe they do not use SPDY anymore. That may be true operationally, but if a reachable Netty pipeline still contains SpdyFrameCodec, the decoder path still exists. Protocol deprecation is not a mitigation if the code remains deployed.
Remediation
Upgrade the full Netty line together:
4.1.x->4.1.136.Final4.2.x->4.2.16.Final
Avoid mixed-version io.netty:* deployments. Security fixes in Netty frequently land as a coordinated set across modules and tests, and partial upgrades are a good way to trade a known exposure for dependency drift.
For prioritization:
- patch externally reachable STOMP services first, because the published PoC is extremely cheap;
- then patch any service that still exposes SPDY through
SpdyFrameCodec; - if an immediate upgrade is blocked, remove or disable unused SPDY support and put strict request-size / connection-rate controls in front of STOMP endpoints.
The broader lesson from this July Netty train is that transport decoders are part of the application security boundary. When a library is willing to allocate based on attacker-controlled header counts, attacker-controlled map cardinality, or attacker-controlled compressed expansion, the bug may live in infrastructure code, but the outage still belongs to the application team that shipped it.
From research to remediation
Check whether this pattern exists in your codebase
Turn this research into a remediation workflow. Scan dependencies and package manifests for similar supply-chain risk, then prioritize fixes with reachability context.