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-88975

CVE-2026-88975: Heap Memory Exhaustion via Malicious HTTP/2 Frame Size in http4s Ember

Amit Schendel
Amit Schendel
Senior Security Researcher

Sep 16, 2026·6 min read·20 visits

Executive Summary (TL;DR)

Unauthenticated remote peers can trigger heap memory exhaustion and Denial of Service in http4s Ember HTTP/2 implementations by sending frames with large declared size headers.

An uncontrolled resource consumption vulnerability in the http4s Ember HTTP/2 server and client implementation leads to unauthenticated heap memory exhaustion and denial of service. The vulnerability stems from deferring frame size validation until the entire declared payload size is buffered.

Vulnerability Overview

The vulnerability affects http4s, a minimal and idiomatic Scala interface for HTTP services. Specifically, the flaw exists within the HTTP/2 implementation of Ember, which is the built-in, native HTTP server and client backend for http4s. Ember exposes an attack surface to remote unauthenticated clients when configured to handle HTTP/2 traffic.

The vulnerability is classified under CWE-400 (Uncontrolled Resource Consumption) and manifests as an application-level Denial of Service. Because the read loop process fails to enforce limits early, it allows arbitrary remote hosts to dictate resource allocation boundaries before validating them. This behavior results in a high-severity availability issue that affects both servers and clients leveraging the vulnerable component.

Root Cause Analysis

HTTP/2 protocol specifications (RFC 9113) define communication through distinct binary frames. Each frame begins with a fixed 9-byte header followed by a variable-length payload. The first three bytes of this header encode a 24-bit integer representing the payload length. During connection negotiation, receiving endpoints advertise their maximum allowable frame size via the SETTINGS_MAX_FRAME_SIZE parameter. The default value is 16 KiB, and it may be negotiated up to 16 MiB.

In vulnerable versions of http4s Ember, the H2Connection.readLoop function reads incoming TCP streams and appends data to an internal accumulator. The read loop holds these bytes in memory until the accumulator length is at least equal to the declared length of the frame plus the 9-byte header. The code does not check the declared length against the configured SETTINGS_MAX_FRAME_SIZE until the reassembly of the frame is complete.

Consequently, a remote peer can declare a massive frame payload size of up to 16 MiB while providing minimal payload data. The server keeps the stream buffer open and continues allocating memory in an attempt to fulfill the expected payload length. If multiple malicious connections execute this sequence simultaneously, the accumulated buffers deplete the Java Virtual Machine heap, leading to severe memory pressure.

Code-Level Vulnerability and Patch Walkthrough

The vulnerability was addressed in commit 87cf334fa3f608ef7d3eb359e71e037ba3336d29 by shifting the frame size check into the earliest stage of the read loop.

Historically, the read loop evaluated the frame only after complete reassembly using the fromByteVector parser. This parsing method deferred validation until all bytes defined by the header were already buffered.

// Vulnerable Read Loop Behavior
// The loop accumulated socket data and only parsed it after
// receiving the entire declared frame payload
H2Frame.RawFrame.fromByteVector(acc) match {
  case Some((rawFrame, remaining)) => 
    // Post-reassembly check occurs here within specific handlers
    // after the allocation has already occurred
}

The security patch introduced a pre-buffering validation phase. It implemented a helper method named peekDeclaredLength within H2Frame.scala to extract the declared size directly from the first 3 bytes of the buffer without waiting for the payload.

// Patched Implementation in H2Frame.scala
object RawFrame {
  /** 
   * The payload length a frame declares, decoded from the first three bytes.
   * Allows an oversized frame to be rejected without reading that payload.
   */
  def peekDeclaredLength(bv: ByteVector): Option[Int] = 
    if (bv.length >= 3) 
      Some((bv(2) & 0xff) | ((bv(1) & 0xff) << 8) | ((bv(0) & 0xff) << 16))
    else None
}

The H2Connection.readLoop was updated to perform a proactive check against this value immediately as bytes are received. If the declared size exceeds the local settings limit, the connection is instantly closed.

// Proactive Validation Check in H2Connection.scala
} else if (
  H2Frame.RawFrame.peekDeclaredLength(acc).exists(_ > localSettings.maxFrameSize.frameSize)
) {
  logger.warn(
    "Received Frame Size Larger than Allowed Frame Size - Frame Size Error - Issuing GoAway"
  ) >> goAway(H2Error.FrameSizeError) >> F.pure(None)
} else 
  H2Frame.RawFrame.fromByteVector(acc) match { 
    // Process valid frame
  }

Exploitation Methodology

An attack targeting this vulnerability is carried out over an established HTTP/2 connection. No authentication credentials or special application-level privileges are required. The attacker only needs network-level access to the port on which the Ember-based service is listening.

The attack sequence is executed in the following steps:

During the attack, the peer transmits an initial frame header stating a size of 16 MiB. The attacker then either pauses transmission or trickles a minimal volume of bytes. The vulnerable server pauses processing of subsequent frames on that connection and retains the growing buffer in memory while waiting for the payload completion. By establishing multiple concurrent streams, the attacker triggers memory amplification up to 1024-fold per connection, leading to a denial of service.

Impact Assessment

The impact of successful exploitation is localized entirely to the availability of the application. There is no risk of unauthorized disclosure of confidential data, nor is there any opportunity for unauthorized modification of system data. This is reflected in the CVSS v3.1 vector string: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H.

The consequences on the JVM runtime include memory fragmentation, prolonged garbage collection pauses, and eventually an OutOfMemoryError. Once an OutOfMemoryError occurs, the JVM may become completely unresponsive or terminate abruptly, necessitating a manual restart or process-manager recovery.

At the time of writing, there are no known public weaponized exploit frameworks targeting this specific flaw. Additionally, the vulnerability is not listed in the CISA Known Exploited Vulnerabilities catalog.

Remediation and Detection Guidance

The primary remediation strategy is upgrading the http4s dependencies to the patched releases. For projects using the 0.23.x release line, upgrade to version 0.23.37 or newer. For projects utilizing the 1.0.0 milestone line, upgrade to version 1.0.0-M48 or newer.

// Example sbt build definition update
libraryDependencies += "org.http4s" %% "http4s-ember-server" % "0.23.37"

If upgrading is not immediately possible, you can mitigate the vulnerability by disabling HTTP/2 support on your Ember servers. This forces clients to fallback to HTTP/1.1, bypassing the vulnerable code path in H2Connection entirely.

// Ensuring HTTP/2 is not enabled on EmberServerBuilder
val server = EmberServerBuilder
  .default[IO]
  .withHost(host"0.0.0.0")
  .withPort(port"8080")
  .withHttpApp(httpApp)
  // Do not call .withHttp2 or .withHttp2(true)
  .build

To detect exploitation attempts, check server log files for the warning message: Received Frame Size Larger than Allowed Frame Size - Frame Size Error - Issuing GoAway. This pattern indicates the updated security logic is rejecting connection streams.

Fix Analysis (1)

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

Affected Systems

http4s-ember-serverhttp4s-ember-client

Affected Versions Detail

Product
Affected Versions
Fixed Version
http4s-ember-server
http4s
< 0.23.370.23.37
http4s-ember-client
http4s
< 0.23.370.23.37
http4s-ember-server
http4s
>= 1.0.0-M1 < 1.0.0-M481.0.0-M48
http4s-ember-client
http4s
>= 1.0.0-M1 < 1.0.0-M481.0.0-M48
AttributeDetail
CWE IDCWE-400
Attack VectorNetwork
CVSS Severity7.5 (High)
Exploit StatusNone
ImpactDenial of Service

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Impact
CWE-400
Uncontrolled Resource Consumption

The software does not properly control the allocation and maintenance of a limited resource, thereby enabling an actor to influence the amount of resources consumed.

Vulnerability Timeline

Vulnerability fix patch committed to codebase
2026-09-06
Security Advisory and CVE-2026-88975 published
2026-09-15

References & Sources

  • [1]GitHub Security Advisory GHSA-gq9p-f254-h286
  • [2]Fix Commit in GitHub
  • [3]v0.23.37 Release Notes
  • [4]v1.0.0-M48 Release Notes
  • [5]CVE-2026-88975 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

•about 2 hours ago•CVE-2026-119282
7.3

CVE-2026-119282: OS Command Injection via Plugin Options in Nx (@nx/maven and @nx/gradle)

An OS command injection and argument injection vulnerability exists in the Nx build system and its official Maven (@nx/maven) and Gradle (@nx/gradle) plugins. When constructing the project dependency graph, the plugins invoke underlying Java build wrappers via subshells while interpolating unsanitized plugin options directly from nx.json into the command arguments. An attacker who supplies a crafted nx.json file via a repository or pull request can execute arbitrary shell commands with the privileges of the user or CI/CD runner invoking any Nx command that computes the project graph.

Amit Schendel
Amit Schendel
4 views•10 min read
•about 3 hours ago•CVE-2026-59978
7.5

CVE-2026-59978: Persistent Denial of Service via Array Injection in AdminNeo

AdminNeo versions 4.6.2 through 5.4.1 contain an improper input validation vulnerability (CWE-20) in the version verification endpoint (?script=version). An unauthenticated remote attacker can submit a crafted HTTP POST request containing an array parameter for 'version', which is serialized into a shared server-side temporary cache file without type checking or authentication. On subsequent requests, the application deserializes this cached array and passes it to cookie() and rawurlencode(), triggering an uncaught fatal TypeError in PHP 8.x environments and causing a persistent 24-hour Denial of Service (DoS) for all users.

Amit Schendel
Amit Schendel
4 views•8 min read
•about 4 hours 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
5 views•12 min read
•about 5 hours 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
4 views•10 min read
•about 6 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
4 views•9 min read
•about 7 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
8 views•10 min read