Addressing CVE-2023-44487: An Overview and Quarkus Solution

You may have encountered the infamous CVE-2023-44487, a security vulnerability directly affecting HTTP/2 servers. This CVE exploits a specific weakness within the HTTP/2 protocol, causing a ripple effect across all HTTP/2 servers.

However, the impact of this CVE is not uniform across all servers; it varies depending on the server’s underlying technology and execution model.

The consequences can range from severe, such as potential Distributed Denial of Service (DDoS) attacks or even server crashes, to relatively minor, manifesting as only a slight increase in CPU usage. This variance in impact is the reason behind the differing CVE scores, ranging from 7.3 for the former scenario to 5.3 for the latter.

Quarkus falls into the 5.3 category, where the impact is less pronounced in practice.

Nevertheless, we take all security-related issues seriously and, following our security policy, we have released the following version updates for Quarkus platform:

Similarly, Red Hat Build of Quarkus includes the CVE fixes in its current release cycle:

Let’s delve deeper into the problem to understand better the distinctions and our approach to resolving it.

Understanding the HTTP/2 CVE

When you browse a website that supports HTTP/2, such as https://quarkus.io, it enables the use of a single connection to fetch numerous resources, including the index page, images, JavaScript scripts, fonts, CSS files, and more. This eliminates the need for the browser to repeatedly establish new connections for each resource, resulting in a more efficient and faster browsing experience. Furthermore, HTTP/2 doesn’t require the browser to wait for a response before sending another request.

This streaming capability of HTTP/2 enhances application concurrency and minimizes network costs, as it reduces the need for numerous connections. Nevertheless, this feature can pose challenges, as a single connection can generate a multitude of requests. To address this, HTTP/2 offers a means of restraining the number of active concurrent streams to prevent clients from overburdening the server. This control is a server-side setting. When a client connects, the server communicates its maximum allowable concurrency. In Quarkus, the ceiling for concurrent streams is set at 100 by default. This limit can be customized using the quarkus.http.limits.max-concurrent-streams property.

When a client exceeds the permitted stream limit, the server responds with an RST_STREAM frame, closing the specific stream without severing the connection, safeguarding against stream flooding.

But there’s more to the story. In HTTP/2, both the client and server maintain stream status, eventually syncing. Unlike HTTP 1.1, HTTP/2 permits clients to gracefully cancel in-flight requests using the RST_STREAM frame. On the client side, the stream closes upon frame transmission, while the server-side closure happens upon processing. This cancellation doesn’t impact other streams in the same connection.

The CVE-2023-44487 attack capitalizes on rapid stream cancellations. While the client closes streams, the server-side closure lags, effectively bypassing the client’s stream limit. This allows the client to open an excessive number of streams, up to 1,073,741,824. During the attack, the client initiates a request via a HEADERS frame in a new stream and immediately dispatches the RST_STREAM frame. From the client’s viewpoint, the stream closes. However, the server must allocate resources to process the RST_STREAM frame, ultimately closing the associated stream.

Threads vs event-loops

As the client repeatedly opens and cancels streams in quick succession, the server grapples with handling RST_STREAM frames and associated bookkeeping. The severity of the attack differs between server technologies. In a one-thread-per-request model, it can be catastrophic, as it consumes all available worker threads, leading to queued HEADERS and RST_STREAM frames and negatively impacting concurrent legitimate requests, thus significantly affecting service availability (CVE score: 7.3/10).

In the case of Netty-based servers (like Quarkus) and other event loop-based servers, the issue is less severe. The incoming frames are placed in the event loop queue, causing higher CPU usage but no thread starvation. Also, Netty handles RST_STREAM frames very efficiently. This may result in higher response times, with the server appearing busy but still managing concurrent legitimate requests. While a problem, its impact on availability is relatively lower (CVE score: 5.3/10).

The Quarkus solution

Due to the high-profile nature of the CVE, Quarkus has taken measures to address this concern. We’ve implemented a solution based on the Netty fix. The system monitors RST_STREAM frames sent per connection, imposing a 200-frame limit within a 30-second window. If the threshold is exceeded, Quarkus takes action by closing the connection and issuing a GOAWAY frame. This procedure closes the connection and all currently active streams associated with it.

While these default settings effectively counter the attack, we understand the need for flexibility. In the upcoming Quarkus 3 release, users will have the option to fine-tune these thresholds, allowing you to customize the configuration to meet your specific requirements, including reducing the maximum number of concurrent streams (already possible today), adjusting the number of RST_STREAM frames, and modifying the time window for attack detection.

Summary

The HTTP/2 CVE is serious and can be used for Distributed Denial of Service attacks, especially if the implementation is thread based. Quarkus is using Netty which is based on an event loop model and thus Quarkus is not as badly affected.

We take all security-related issues seriously and following our security policy, we have released the following version updates for Quarkus platform:

Similarly, Red Hat Build of Quarkus includes the CVE fixes in its current release cycle:

All these versions contain the fix described in this article.

We strongly recommend updating your application to one of these versions.