Jul 25, 2026·5 min read·4 visits
Unbounded WebSocket message aggregation in http4s-blaze-server allows unauthenticated remote attackers to crash the server with an OutOfMemoryError via a stream of tiny continuation fragments.
An uncontrolled resource consumption vulnerability exists in the Scala-based http4s-blaze-server package of the http4s/blaze library. The vulnerability allows remote, unauthenticated attackers to cause an Out of Memory Error (OOM) and JVM crash by streaming a continuous sequence of small or empty WebSocket continuation frames with the FIN bit set to 0. This bypasses typical payload size checks because of the JVM's per-object allocation overhead, leading to rapid heap exhaustion with minimal network bandwidth.
An uncontrolled resource consumption vulnerability exists in the http4s-blaze-server component of the Scala HTTP library ecosystem. The vulnerability is classified under CWE-400 (Uncontrolled Resource Consumption) and CWE-770 (Allocation of Resources Without Limits or Throttling).
The vulnerability is located within the server's WebSocket message aggregation system. WebSocket connections that use message fragmentation can be manipulated by an unauthenticated remote attacker to consume unbounded amounts of heap memory on the host Java Virtual Machine (JVM). This resource exhaustion can occur regardless of the actual data payload size transmitted over the network.
Because the underlying library did not impose a limitation on the number of accumulated fragments or the overall size of buffered payloads, it created a severe vector for remote Denial of Service (DoS) attacks. The threat can be realized through low-bandwidth streams of small frames, making traditional traffic rate-limiting or firewall payload checks ineffective.
The root cause of this vulnerability lies in the implementation of the WSFrameAggregator class inside the http4s-blaze-server packet pipeline. This component is designed to reconstruct fragmented WebSocket frames according to RFC 6455 specifications.
RFC 6455 permits a WebSocket message to be split into multiple frames starting with a non-final frame (FIN=0) and followed by any number of continuation frames (opcode 0x0, FIN=0). The aggregation layer stores incoming fragments within an internal Scala queue called the Accumulator until a frame with the FIN bit set to 1 is received.
Two critical flaws occurred within this processing model. First, there was no cap on the maximum cumulative payload size of aggregated messages. Second, and more importantly, each incoming frame requires the allocation of several JVM metadata objects, including a WebSocketFrame instance, an internal ByteVector wrapper, and list elements within Scala's mutable.Queue. This metadata represents approximately 64 bytes of object overhead per frame on the JVM heap. An attacker can stream millions of 0-byte continuation frames to exhaust heap memory using minimal network transit.
Before the patch, WSFrameAggregator lacked size checks during its accumulation cycle, allowing the internal Accumulator queue to grow without bounds. This section demonstrates how the patch resolves this memory leak.
// Patched message size validation helper
private[this] def messageTooLarge(next: WebSocketFrame): Boolean = {
val charged = accumulator.length.toLong + next.length.toLong +
(accumulator.frames.toLong + 1L) * WSFrameAggregator.FragmentOverheadBytes
maxMessageSize > 0 && charged > maxMessageSize.toLong
}To address object metadata expansion, the patch charges a virtual penalty of 64 bytes (FragmentOverheadBytes) for each accumulated fragment. This prevents the queue from expanding indefinitely even when receiving empty payloads. When the computed size exceeds maxMessageSize, the accumulator is purged, and a WebSocketMessageTooLargeException is thrown.
Additionally, the patch links the maximum size thresholds between the frame aggregator and the low-level frame decoder, preventing single-frame buffer exploits:
// Aligning aggregator and decoder bounds
val wsMaxMessageSize =
maxBufferSize.getOrElse(WSFrameAggregator.DefaultMaxMessageSize)
...
.prepend(new WSFrameAggregator(wsMaxMessageSize))
.prepend(new WebSocketDecoder(wsMaxMessageSize))Exploitation of GHSA-7PPR-R889-MCF2 can be executed by an unauthenticated remote adversary with network access to a WebSocket endpoint exposed by an affected http4s-blaze-server instance.
The attack flow is executed as follows:
By withholding the final frame (FIN=1), the attacker ensures that the server's WSFrameAggregator maintains state and continues to allocate memory structures on the heap. This causes the JVM to consume heavy CPU cycles attempting garbage collection before crashing with an OutOfMemoryError.
The impact of a successful exploit against GHSA-7PPR-R889-MCF2 is high. Since the http4s-blaze-server process runs inside a single JVM container, an OutOfMemoryError will terminate the active thread pool or cause the JVM process to crash. This completely disrupts service for all active users.
Because the vulnerability requires no special privileges and does not depend on specific application states or configurations, any endpoint supporting WebSockets is fully exposed. The CVSS score for this vulnerability is assessed at 7.5 (High) under vector string CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H.
Because GHSA-7PPR-R889-MCF2 is an advisory published within the GitHub Advisory Database without a matching CVE ID, organizations relying on basic CVE scanner databases may fail to recognize the exposure of their software. This necessitates active dependency audits of all Scala microservices using the http4s backend.
To remediate the vulnerability, users must upgrade their dependencies to one of the patched versions: 0.23.18 or 1.0.0-M42. These releases configure WSFrameAggregator to use a default 4 MiB payload cap and apply the per-fragment overhead penalty.
If upgrading is not immediately possible, the following mitigations can reduce exposure:
BlazeServerBuilder is not configured with negative or zero limits, which will bypass the newly introduced security boundaries.// Secure configuration example enforcing validation:
BlazeServerBuilder[IO]
.bindHttp(8080, "0.0.0.0")
.withMaxWebSocketBufferSize(4 * 1024 * 1024) // 4MB maximum bufferCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
http4s-blaze-server http4s | < 0.23.18 | 0.23.18 |
http4s-blaze-server http4s | < 1.0.0-M42 | 1.0.0-M42 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-400 |
| Attack Vector | Network |
| CVSS | 7.5 |
| Impact | Denial of Service (DoS) |
| Exploit Status | None (PoC verified theoretically) |
| KEV Status | Not Listed |
The product does not properly control the allocation and maintenance of a limited resource, enabling an actor to cause a resource depletion.
A critical path traversal vulnerability has been identified in the OpenList Go-based backend package. The vulnerability exists within the batch rename handler because the application does not validate the source filename parameter before constructing filesystems paths. This omission allows authenticated users to escape their designated directory and rename files in sibling paths.
OpenList version 4.2.3 and prior is vulnerable to an authorization bypass and metadata leakage. When configured with the Bleve search engine backend, OpenList fails to perform separator-aware path matching when validating tenant containment. This allows authenticated users to access sibling directories sharing similar name prefixes. Furthermore, the search backend returns unfiltered global result counts, leaking existence verification data of unauthorized files via side-channel analysis.
An authorization bypass vulnerability in OpenList version 4.2.3 and below allows authenticated users to read arbitrary files outside of their designated base directories due to an insecure path prefix check using Go's standard strings.HasPrefix function.
A security policy bypass vulnerability exists in the AWS API MCP Server (awslabs-aws-api-mcp-server) from version 0.2.13 through 1.3.46. When the server fails to load the read-only operations index during startup (due to transient network failures, file permission issues, or other exceptions), it logs a warning but continues running in an insecure, degraded state. Under this condition, the security policy engine fails open, silently skipping all subsequent security checks and consent prompts for the lifetime of the process. This permits unauthorized mutating AWS CLI commands to execute via indirect prompt injection attacks.
An incomplete escaping vulnerability in the npm package 'shescape' allows unauthenticated users to trigger dynamic shell expansions, absolute path disclosure, and command block break-outs on Unix and Windows systems.
A critical command injection vulnerability in the shescape npm library affects Windows systems when running shell commands using cmd.exe. The escaping function fails to neutralize parentheses, allowing attackers to close shell blocks and execute arbitrary commands.