Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2023-26964: Stream stacking occurs when H2 processes HTTP2 RST_STREAM frames. As a result, the memory and CPU usage are high. · Issue #2877 · hyperium/hyper

An issue was discovered in hyper v0.13.7. h2-0.2.4 Stream stacking occurs when the H2 component processes HTTP2 RST_STREAM frames. As a result, the memory and CPU usage are high which can lead to a Denial of Service (DoS).

CVE
#vulnerability#dos

Version
hyper-0.13.7
h2-0.2.4

Platform
wsl

Description

Summary:

​ Stream stacking occurs when Hyper processes HTTP2 RST_STREAM frames. As a result, the memory and CPU usage are high.

Step:

  1. Send an HEADERS frame to open the stream, followed by an RST_STREAM frame to request cancellation of the stream

    def reset_flood(h2_conn):
        for i in range(1, 20000):
            if i % 2 == 0:
                continue
            headers(h2_conn, i)
            rst_stream(h2_conn, i)
    
  2. Create multiple threads for sending.

    if __name__ == '__main__':
        for i in range(0, 400):
            try:
                _thread.start_new_thread(send, ("Thread-" + str(i),))
            except:
                print("Error: Can not start thread")
        while 1:
            pass
    

Result:

The CPU usage of the Hyper server keeps increasing. As a result, the VM memory is used up.

Vulnerability analysis:

When receiving a HEADERS frame, the h2 stores the corresponding stream content in the slab and sets a frame index to the ids. When receiving an RST_STREAM frame, h2 sets the stream to Closed and resets the related statistics. However, the stream memory is released only when stream.is_released() is true . When the RST_STREAM frame is received, the release is not triggered immediately. As a result, the size of the slab increases continuously.

Test procedure:

Add the slab_len(),ids_len() method for Store to return the length of all flows and active flows.

Add the preceding two stream lengths to the recv_reset() method.

After the test, when the HEADERS frame is repeatedly sent to open a stream or the RST_STREAM frame is sent to cancel the stream, the length of the ids does not exceed the value of max_recv, but the SLAB increases .The stream in the Closed state in the SLAB is released only after all frames on the connection are sent.

The max_concurrent_streams configuration can limit max_recv_streams, but it appears that in this scenario, the size of Slab is much larger than the max_concurrent_streams value and stacks up.

I think it is necessary to limit the size of the Slab or ensure that streams in the Slab can be released quickly after the RST_STREAM frame is received to prevent such attacks.

Related news

GHSA-f8vr-r385-rh5r: hyper and h2 vulnerable to denial of service

Hyper is an HTTP library for Rust and h2 is an HTTP 2.0 client & server implementation for Rust. An issue was discovered in hyper v0.13.7 and h2 v0.2.4 when proessing header frames. Both packages incorrectly process the HTTP2 `RST_STREAM` frames by not always releasing the memory immediately upon receiving the reset frame, leading to stream stacking. As a result, the memory and CPU usage are high which can lead to a Denial of Service (DoS). As of time of publication of this advisory, there is no evidence of a fix having been incorporated into hyper or h2.

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda
CVE-2023-6905
CVE-2023-6903
CVE-2023-6904
CVE-2023-3907