CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-48748

CVE-2026-48748: Netty HTTP/3 QPACK Blocked Streams Memory Exhaustion

Amit Schendel
Amit Schendel
Senior Security Researcher

Jun 16, 2026·6 min read·69 visits

Executive Summary (TL;DR)

A boundary check bypass and memory leak in Netty's HTTP/3 QPACK decoder allow remote attackers to exhaust JVM memory and crash servers via an unrestricted number of blocked streams.

CVE-2026-48748 is a denial-of-service vulnerability in Netty's HTTP/3 codec (netty-codec-http3) occurring when QPACK dynamic tables are enabled but the blocked streams limit is not explicitly configured. A bug in limit checking and a memory leak in stream tracking allow unauthenticated remote attackers to exhaust the JVM heap memory and crash the server.

Vulnerability Overview

The HTTP/3 protocol uses QPACK (RFC 9204) for efficient compression of HTTP headers over QUIC. QPACK introduces a dynamic table containing header fields that are added incrementally during the lifetime of a connection. This mechanism necessitates handling out-of-order header delivery. When an HTTP/3 client sends a header referencing a dynamic table entry that the server has not yet parsed, the server must pause (block) processing of that stream until the prerequisite instructions arrive.

To prevent resource exhaustion attacks, servers must enforce strict upper limits on the number of concurrent blocked streams. In Netty's HTTP/3 codec (io.netty:netty-codec-http3), this limit is tracked using the maxBlockedStreams setting. A flaw in how Netty validates this limit combined with a failure to release tracking state leads to heap exhaustion.

This analysis details CVE-2026-48748, a high-severity resource exhaustion vulnerability affecting Netty HTTP/3 implementations. Unauthenticated remote attackers can exploit this vulnerability to trigger JVM heap memory exhaustion, resulting in a persistent Denial of Service.

Root Cause Analysis

The vulnerability resides within the QPACK decoding engine of Netty, specifically inside the class io.netty.handler.codec.http3.QpackDecoder and its helper method shouldWaitForDynamicTableUpdates. The primary defect is a logical flaw in the boundary check used to enforce the concurrent blocked stream limit.

When a server enables QPACK dynamic tables (by defining HTTP3_SETTINGS_QPACK_MAX_TABLE_CAPACITY greater than zero) but relies on default parameters, the setting HTTP3_SETTINGS_QPACK_BLOCKED_STREAMS remains unconfigured. Under these conditions, the property maxBlockedStreams defaults to a value of 0. The implementation checks the current count of blocked streams using the expression if (blockedStreamsCount == maxBlockedStreams - 1). When maxBlockedStreams is 0, this condition evaluates to if (blockedStreamsCount == -1). Because blockedStreamsCount starts at zero and only increments upon blocking new streams, the check can never evaluate to true. Consequently, the limit is bypassed entirely.

Furthermore, the QpackDecoder contains a secondary memory leak defect. When a stream is successfully unblocked or closed, the decoder does not remove the stream's metadata from its internal blockedStreams tracking data structure, nor does it decrement the blockedStreamsCount counter. This lack of cleanup ensures that memory allocated for the ReadResumptionListener and associated stream context persists for the duration of the QUIC connection, creating a severe memory leak.

Code Analysis

To understand the vulnerabilities, analyze the following representation of the vulnerable QpackDecoder implementation:

// Vulnerable Implementation
public boolean shouldWaitForDynamicTableUpdates(long streamId, long requiredIndex) {
    // ... other checks ...
    
    // Flaw 1: Integer subtraction vulnerability leading to bypass
    // When maxBlockedStreams is 0, (maxBlockedStreams - 1) equals -1
    if (blockedStreamsCount == maxBlockedStreams - 1) {
        throw new Http3Exception(Http3ErrorCode.H3_QPACK_DECOMPRESSION_FAILED, "Limit exceeded");
    }
    
    // Flaw 2: Allocation without release
    ReadResumptionListener listener = new ReadResumptionListener(streamId);
    blockedStreams.put(streamId, listener);
    blockedStreamsCount++; // Incremented but never decremented
    
    return true;
}

The fix implemented in Netty version 4.2.15.Final addresses both structural flaws. It corrects the mathematical validation and ensures appropriate resource cleanup when a stream is processed or closed. The patched code implements the validation logic and cleanup actions:

// Patched Implementation
public boolean shouldWaitForDynamicTableUpdates(long streamId, long requiredIndex) {
    // ... other checks ...
    
    // Fix 1: Robust boundary check prevents bypass when limit is 0 or low
    if (blockedStreamsCount >= maxBlockedStreams) {
        throw new Http3Exception(Http3ErrorCode.H3_QPACK_DECOMPRESSION_FAILED, "Limit exceeded");
    }
    
    ReadResumptionListener listener = new ReadResumptionListener(streamId);
    blockedStreams.put(streamId, listener);
    blockedStreamsCount++;
    
    return true;
}
 
// Fix 2: Proper resource deallocation
public void onStreamClosed(long streamId) {
    ReadResumptionListener removed = blockedStreams.remove(streamId);
    if (removed != null) {
        blockedStreamsCount--;
    }
}

The replacement of the exact-match condition (== maxBlockedStreams - 1) with a relational inequality check (>= maxBlockedStreams) prevents bypass regardless of the configuration value. The addition of the tracking cleanup in onStreamClosed or equivalent lifecycle handlers prevents memory from growing indefinitely.

Exploitation Methodology

An attacker can exploit this vulnerability with standard HTTP/3 traffic. The exploit requires no authentication or specific system state, only the ability to establish an HTTP/3 connection with the target server.

The attacker initiates standard HTTP/3 handshakes and configures the connection to negotiate QPACK support. The attacker then continuously issues streams containing HTTP headers that deliberately reference dynamic table entries that have not yet been defined. The Netty decoder blocks each stream and registers a ReadResumptionListener in heap memory.

Because the boundary condition is broken and the cleanup is non-existent, the attacker can pile up hundreds of thousands of blocked streams on a single QUIC connection. This monotonically increases heap allocations until the JVM runs out of memory, leading to an abrupt application crash.

Impact Assessment

The impact of CVE-2026-48748 is classified as a high-severity Denial of Service (DoS). The vulnerability allows a single unauthenticated attacker to completely exhaust system memory resources on the hosting platform, resulting in an OutOfMemoryError (OOM) inside the Java Virtual Machine.

Because Netty is widely used as an underlying networking engine for various high-throughput proxy servers, API gateways, and microservice frameworks, a crash of the Netty runtime halts all dependent network services. This creates a complete service outage.

No data confidentiality or integrity is directly compromised, as the exploit does not permit unauthorized read or write access to application memory. The CVSS base score is determined to be 7.5.

Remediation and Mitigation Guidance

The primary remediation is upgrading io.netty:netty-codec-http3 to version 4.2.15.Final or later. This version contains the complete correction for both the limit-validation expression and the memory-cleanup omissions.

If immediate patching is not possible, a temporary workaround is available. Administrators must explicitly configure the setting HTTP3_SETTINGS_QPACK_BLOCKED_STREAMS to a non-zero integer, such as 100. Doing so prevents the maxBlockedStreams variable from defaulting to 0, ensuring that the vulnerable condition blockedStreamsCount == maxBlockedStreams - 1 triggers once the threshold is approached.

Note that because of the memory tracking leak, once the limit is reached, the connection will permanently refuse to block further streams, which may cause degradation of long-lived connections. However, this protects the server from infinite heap growth and subsequent JVM crashes. This workaround should be treated as a short-term risk reduction strategy until patches are applied.

Technical Appendix

CVSS Score
7.5/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
EPSS Probability
0.49%
Top 62% most exploited

Affected Systems

io.netty:netty-codec-http3Netty HTTP/3-enabled web serversAPI gateways using Netty for HTTP/3

Affected Versions Detail

Product
Affected Versions
Fixed Version
netty-codec-http3
Netty
>= 4.2.0.Final, < 4.2.15.Final4.2.15.Final
AttributeDetail
CWE IDCWE-770
Attack VectorNetwork (AV:N)
CVSS Score7.5
EPSS Score0.00488
ImpactAvailability (Denial of Service via JVM OOM)
Exploit StatusPoC
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Impact
CWE-770
Allocation of Resources Without Limits or Throttling

Vulnerability Timeline

Vulnerability identified and patched in Netty release 4.2.15.Final
2026-02-01
GitHub Security Advisory and NVD entry published
2026-02-15

References & Sources

  • [1]GitHub Advisory GHSA-4grm-h2qv-h6w6
  • [2]Netty 4.2.15.Final Release Tag
  • [3]NVD Vulnerability Page
  • [4]CVE Record

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•10 minutes ago•GHSA-FGXM-5HVV-X4VH
5.3

GHSA-fgxm-5hvv-x4vh: Private Repository Enumeration via Go Module Discovery and HTTP Response Discrepancies in Soft Serve

Charmbracelet Soft Serve versions 0.5.0 through 0.12.2 contain an authorization bypass and observable response discrepancy vulnerability in the HTTP Git server. Remote attackers can determine the existence, exact names, and clone URLs of private repositories by issuing crafted Go remote import path discovery requests (?go-get=1) or by observing differential HTTP status codes across Git Smart HTTP, Dumb HTTP, and Git LFS endpoints.

Alon Barad
Alon Barad
0 views•12 min read
•about 1 hour ago•GHSA-F3FJ-9625-RV3M
5.9

GHSA-f3fj-9625-rv3m: Race Condition in Soft Serve Repository Cache Invalidation

A Time-of-Check to Time-of-Use (TOCTOU) race condition in Charmbracelet Soft Serve versions 0.6.0 through 0.12.2 allows unauthenticated users to retain read access to repositories after their visibility is changed from public to private. The flaw stems from premature cache invalidation in the SetPrivate method prior to committing the visibility update to the underlying database. Concurrent read requests arriving during the database transaction window repopulate the non-expiring in-memory LRU cache with stale public metadata, bypassing access controls across HTTP, SSH, and Git protocols until the server process is restarted.

Alon Barad
Alon Barad
3 views•10 min read
•about 2 hours ago•CVE-2026-119283
7.5

CVE-2026-119283: Unbounded JWE Recipients Array Causes CPU Exhaustion in Authlib joserfc

A resource consumption vulnerability exists in the Authlib joserfc Python library prior to version 1.7.5. When processing JSON Web Encryption (JWE) objects formatted using General JSON Serialization, the library fails to enforce an upper bound on the number of elements within the recipients array. An unauthenticated attacker can supply a JWE containing thousands of recipient entries targeting an RSA key management algorithm, forcing the server to perform an equivalent number of computationally expensive RSA private-key decryption operations per request and exhausting available CPU resources.

Alon Barad
Alon Barad
2 views•9 min read
•about 3 hours ago•CVE-2026-119284
6.9

CVE-2026-119284: Uncontrolled Resource Consumption in joserfc Compact Deserialization

CVE-2026-119284 (GHSA-9pg5-8c7x-5hfx) is an uncontrolled resource consumption vulnerability (CWE-400) in the compact serialization deserialization routines of joserfc prior to version 1.7.6. The library enforced individual segment size limits only after invoking Python's bytes.split(b'.') on untrusted input tokens. By sending oversized compact JWS or JWE tokens, an unauthenticated remote attacker can force the Python interpreter to duplicate and allocate memory for every segment before size validation executes, resulting in memory exhaustion and an Endpoint Denial of Service (DoS).

Amit Schendel
Amit Schendel
7 views•10 min read
•about 10 hours ago•GHSA-C33X-VCV4-VG3G
2.1

GHSA-c33x-vcv4-vg3g: Missing Slot Identifier Validation in Cedar Policy Language JSON Template Parser Causes Panic and Authorization Divergence

An improper input validation vulnerability (CWE-20) exists in the Entity Syntax Tree (EST) JSON deserialization component of the Cedar Policy Language (`cedar-policy` and `@cedar-policy/cedar-wasm`). When parsing JSON-formatted policy templates that define `is ... in` scope constraints on `principal` or `resource`, the parser used wildcard pattern matching that ignored the provided slot identifier (`?principal` or `?resource`). This omission allows malformed JSON templates to bypass initial deserialization validation, resulting in either a runtime panic during template linking or inverted slot bindings that alter authorization outcomes.

Amit Schendel
Amit Schendel
7 views•10 min read
•about 11 hours ago•GHSA-W9X9-J56R-H98R
8.2

GHSA-w9x9-j56r-h98r: Unauthenticated Confused Deputy Proxy in @eeacms/volto-chatbot

The @eeacms/volto-chatbot package for Plone Volto contains an unauthenticated confused deputy vulnerability (CWE-862) in versions 2.0.3 and earlier. The package registers Express middleware on wildcard proxy routes (`**/_v1_da/**` and `**/_v1_ha/**`) without verifying client authentication or restricting target endpoints. When processing incoming HTTP requests, the middleware automatically attaches server-side administrative credentials before forwarding the requests to upstream Danswer (Onyx) or Halloumi (LLMGW) API servers. This allows unauthenticated network attackers to execute arbitrary administrative API calls against the backend infrastructure.

Amit Schendel
Amit Schendel
6 views•8 min read