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:
-
Latest 3.x: Quarkus 3.4.3 (latest 3.x)
-
3.2 LTS: Quarkus 3.2.7 (3.2 LTS)
-
Latest 2.x: Quarkus 2.16.12.Final
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:
-
Latest 3.x: Quarkus 3.4.3 (latest 3.x)
-
3.2 LTS: Quarkus 3.2.7 (3.2 LTS)
-
Latest 2.x: Quarkus 2.16.12.Final
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.