In a groundbreaking analysis, security researcher Bartek Nowotarski has detailed a new class of vulnerabilities within the HTTP/2 protocol, known as the CONTINUATION Flood. This technical deep dive into HTTP/2‘s inner workings reveals a potential for significant disruptions, overshadowing even the notorious Rapid Reset attack dubbed the largest Distributed Denial of Service (DDoS) attack to date.
The Inherent Flaw
HTTP/2 was designed to improve upon its predecessor HTTP/1.1 by introducing efficiencies such as binary data framing and multiplexing. However, these same features have opened a door for new vulnerabilities. The CONTINUATION Flood exploits an oversight in the handling of CONTINUATION frames—elements used to extend a header block across multiple frames when it’s too large to fit in a single frame.
HTTP/2
- Binary Protocol: Unlike HTTP/1.1, which is text-based, HTTP/2 operates using a binary protocol. This fundamental change enhances efficiency, as binary protocols are generally faster, more compact, and less error-prone compared to text-based ones.
- Frame-based Communication: In HTTP/2, communication between the client and server occurs through frames, rather than plain text lines. This includes various types of frames that serve different functions, such as managing and transmitting data.
- Session Management Frames: Some of the frame types in HTTP/2 are designed not to transmit data but to help configure and manage an HTTP/2 session. Examples include SETTINGS frames for session configuration and WINDOW_UPDATE frames for flow control.
These features mark significant technical improvements over HTTP/1.1, aiming to optimize web browsing by reducing latency, enabling multiplexing, and improving data stream prioritization and server push capabilities.
Example: A Simple HTTP/2 Interaction
Scenario:
Alice wants to view a webpage that includes HTML content, CSS for styling, and several images.
HTTP/2 Features in Use:
- Binary Protocol
- Frame-based Communication
Step-by-Step Process:
- Connection Establishment:
- Alice’s browser initiates a connection to the web server and starts an HTTP/2 session.
- This session will use a binary protocol, meaning all data sent and received is encoded in binary form, not readable text. This makes the data transmission more efficient and less prone to errors common in text-based parsing.
- Sending HTTP Requests (Using Frames):
- Alice’s browser sends a single HTTP/2 HEADERS frame that initiates a new stream for fetching the HTML document. This frame contains compressed HTTP headers using the HPACK format, which reduces header size and improves performance.
- The HEADERS frame is marked with an END_HEADERS flag indicating that it contains all the headers for this request.
- Multiplexing:
- While waiting for the HTML document to be sent back, Alice’s browser can simultaneously send additional HEADERS frames on different streams to request CSS files, images, and other resources needed for the webpage.
- This is done without waiting for the first request to complete, thanks to HTTP/2’s ability to multiplex – sending multiple requests and responses in parallel over the same connection.
- Server Response with Multiple Frames:
- The server responds to each request with its own set of frames:
- DATA frames for the HTML content, each possibly followed by more DATA frames depending on the content size.
- Additional DATA frames on other streams deliver CSS, images, and scripts. These are interleaved, which means parts of the HTML, CSS, and images can be transmitted back-to-back, reducing the overall latency perceived by Alice.
- The server responds to each request with its own set of frames:
- Stream Management:
- Each stream can be individually managed and prioritized, allowing the server to send critical resources like CSS before images if it deems necessary.
- Flow control mechanisms like WINDOW_UPDATE frames ensure that neither the client nor the server overwhelm each other with data, maintaining a smooth flow of communication.
- Session Closure:
- Once all the resources are delivered, and the webpage is fully loaded, the HTTP/2 session can be closed, or kept alive for further interactions.
In this scenario, HTTP/2’s binary protocol and frame-based communication allow Alice to receive webpage components faster and more efficiently compared to HTTP/1.1. The use of multiple streams reduces delays caused by the request-response cycle of HTTP/1.1, while the binary protocol reduces the overhead of parsing and transmitting textual data.
HEADERS frame
The HEADERS frame in HTTP/2 is a fundamental component of the protocol’s communication structure, used to carry header data necessary for HTTP requests and responses. Understanding its function and characteristics can provide insight into how HTTP/2 improves upon previous HTTP standards like HTTP/1.1. Here’s a detailed look at the HEADERS frame:
Function of the HEADERS Frame
The HEADERS frame’s primary purpose is to carry HTTP headers for a request or response. Headers in HTTP are key-value pairs that carry information about the HTTP transaction, such as the requested URL, status code for responses, and other metadata related to HTTP operations.
Characteristics of the HEADERS Frame
- Binary Format: Like all HTTP/2 frames, the HEADERS frame is encoded in a binary format. This choice reduces parsing errors and improves performance over the text-based headers used in HTTP/1.1.
- Compression with HPACK: Headers within a HEADERS frame are compressed using HPACK. HPACK compression reduces redundancy by encoding headers that are frequently sent between client and server. It uses a static table of common HTTP headers and a dynamic table that captures headers seen in the current connection, further optimizing the communication.
- Flags:
- END_STREAM: This flag indicates that the HEADERS frame is the last frame that will be sent on this stream and that there is no accompanying body (e.g., for a GET request).
- END_HEADERS: This flag signifies that this frame contains the final block of headers. If this flag is not set, it means subsequent HEADERS or CONTINUATION frames will follow as part of the same logical set of headers.
- Stream Association: Each HEADERS frame is associated with a specific stream. HTTP/2 can multiplex multiple streams (i.e., different sets of requests and responses) concurrently over the same connection, with each stream handling a separate request-response cycle.
Example Usage of a HEADERS Frame
Consider a scenario where a client makes an HTTP GET request to a server to fetch a webpage:
- Opening a Stream:
- The client initiates a new stream by sending a HEADERS frame. This frame includes HTTP request headers like
:method = GET
,:scheme = https
,:path = /index.html
, and:authority = www.example.com
.
- The client initiates a new stream by sending a HEADERS frame. This frame includes HTTP request headers like
- Server Response:
- The server responds with its own HEADERS frame on the same stream. This response HEADERS frame might include headers such as
:status = 200
and server-related headers likecontent-type = text/html
.
- The server responds with its own HEADERS frame on the same stream. This response HEADERS frame might include headers such as
- Closing the Stream:
- If the response does not require a body, the server might set the
END_STREAM
flag on its HEADERS frame, indicating that no further frames (like DATA frames) will follow for this stream.
- If the response does not require a body, the server might set the
The HEADERS frame, thus, plays a critical role in initiating request-response cycles and carrying necessary metadata in a compact, efficient, and reliable manner within HTTP/2 communications.
CONTINUATION frame
The CONTINUATION frame in HTTP/2 plays a critical role in the protocol’s handling of extensive header sets that exceed the capacity of a single HEADERS frame. Understanding its functionality, structure, and relationship to the HEADERS frame helps clarify how HTTP/2 manages complex and large-scale data transmissions efficiently. Here’s an in-depth look at the CONTINUATION frame:
Function of the CONTINUATION Frame
The CONTINUATION frame is used to continue a sequence of headers when they are too long to fit in a single HEADERS frame. This situation typically occurs when there are either many headers or the headers themselves are large (e.g., cookies packed with data).
Characteristics of the CONTINUATION Frame
- Binary Format: Like all HTTP/2 frames, the CONTINUATION frame is encoded in binary, ensuring efficient processing and transmission.
- Compression with HPACK: Headers within a CONTINUATION frame continue to use HPACK compression, maintaining consistency with how headers are compressed in HEADERS frames.
- Flags:
- END_HEADERS: This is the only flag used with CONTINUATION frames. It signals that this frame concludes the header block started by a preceding HEADERS or CONTINUATION frame. When set, no further CONTINUATION frames are expected for this header block.
- Stream Association: CONTINUATION frames must be associated with the same stream as the initial HEADERS frame that started the header sequence. They cannot be interleaved with other frames on the same stream, which means all CONTINUATION frames must follow directly after the HEADERS frame until the END_HEADERS flag is set.
Example Usage of a CONTINUATION Frame
Let’s illustrate how a CONTINUATION frame is used in a scenario where a client sends a complex request to a server:
Scenario:
Alice’s application sends a request to a server that requires a large set of headers, including numerous custom headers and large cookie values.
Step-by-Step Process:
- Client Sends HEADERS Frame:
- Alice’s application initiates a new stream (Stream 2) and sends a HEADERS frame. However, due to the large number of headers, not all headers can be included in this single frame.
- The HEADERS frame is sent without the
END_HEADERS
flag, indicating that more headers are to follow.
- Client Sends CONTINUATION Frames:
- Immediately following the HEADERS frame, Alice’s application sends one or more CONTINUATION frames. These frames carry the remainder of the headers.
- Each CONTINUATION frame continues the header list started by the HEADERS frame, and none of them set the
END_HEADERS
flag except for the final CONTINUATION frame.
- Final CONTINUATION Frame:
- The last CONTINUATION frame in the sequence sets the
END_HEADERS
flag, signaling that it contains the last segment of headers for this request. - This flag tells the server that it has received all headers for this particular request and can start processing the combined header data.
- The last CONTINUATION frame in the sequence sets the
- Server Processes Request:
- The server receives the HEADERS frame followed by all CONTINUATION frames. It reassembles the complete header set using HPACK decoding.
- Once the full headers are reconstructed, the server processes the request based on the complete header information it has now fully received.
The CONTINUATION frame is essential for handling situations where extensive header information cannot be confined to a single HEADERS frame. By allowing headers to be fragmented and sequentially transmitted, HTTP/2 ensures that even complex requests with extensive metadata can be handled efficiently without sacrificing the integrity or the sequential nature of communications. This mechanism highlights one of the many optimizations that HTTP/2 introduces over HTTP/1.1 to improve web performance and resource management.
Anatomy of the Attack
The attack leverages the fact that the HTTP/2 server expects the header block to end with a frame marked by the END_HEADERS
flag. In a CONTINUATION Flood, attackers maliciously withhold this flag, leading the server to await more headers indefinitely, tying up resources.
Key Vulnerabilities:
- CPU Exhaustion: The server expends CPU resources managing the unfinished headers.
- Memory Overflow: Servers store these headers in memory, expecting an end that never comes, which can lead to a crash or significant slowdown due to memory exhaustion.
- Invisibility to Logs: These incomplete requests often bypass normal logging, complicating detection and response.
Understanding the CONTINUATION Flood Vulnerability
Core Mechanism:
The CONTINUATION frame in HTTP/2 is designed to extend header lists beyond the single frame limit imposed on HEADERS frames. If a HEADERS frame doesn’t fit all headers, additional CONTINUATION frames are used, and the END_HEADERS
flag is only set on the final CONTINUATION frame, indicating the end of the header block.
The vulnerability arises when an attacker intentionally omits the END_HEADERS
flag on CONTINUATION frames, creating what appears to be an indefinitely continuing stream of headers. This stream forces the server to keep allocating resources to handle what it assumes to be an ongoing header block.
Exploit Strategy:
- Infinite Header Blocks: By not setting the
END_HEADERS
flag, an attacker can trick the server into expecting more header data, thereby indefinitely extending the processing time and resource allocation. - Resource Exhaustion: The server may allocate memory and CPU cycles to handle the incoming headers, expecting them to conclude at some point. As this conclusion never arrives, the resources keep being consumed, potentially leading to memory exhaustion or CPU saturation.
- Lack of Visibility: Often, these malformed requests are not properly logged because they don’t form a complete HTTP request. This invisibility makes it difficult to trace and mitigate the attack.
Potential Impacts of a CONTINUATION Flood Attack
- Denial of Service (DoS): Servers may become unresponsive or crash under the strain of processing the endless headers, leading to service outages.
- Server Crash: In severe cases, the server might crash due to unhandled exceptions or resource limits being exceeded (e.g., out of memory errors).
- Performance Degradation: Even if not crashing, the server’s performance may degrade as it diverts resources to handle the fictitious headers, affecting the service quality for legitimate users.
Example Scenario: Online Store Under Attack
Background:
Imagine an online store that uses an HTTP/2 enabled server to handle its web traffic. The server is configured to support the advanced features of HTTP/2, including multiplexing and header compression.
Attack Preparation:
An attacker, aiming to disrupt the online store during a peak shopping period, decides to exploit the CONTINUATION Flood Vulnerability.
Step-by-Step Attack Process:
- Initiating the Attack:
- The attacker crafts a series of HTTP/2 requests to the server. Each request starts normally with a HEADERS frame indicating the beginning of a new HTTP/2 stream.
- These HEADERS frames are purposely designed not to include the
END_HEADERS
flag, suggesting that more header data will follow.
- Sending Malformed CONTINUATION Frames:
- Following each HEADERS frame, the attacker sends CONTINUATION frames. Crucially, these CONTINUATION frames also do not set the
END_HEADERS
flag. - This process is repeated, with the attacker sending a large number of CONTINUATION frames, continually indicating that more headers are to come, but never concluding the header block.
- Following each HEADERS frame, the attacker sends CONTINUATION frames. Crucially, these CONTINUATION frames also do not set the
- Exploiting Server Resource Allocation:
- Each open header block (initiated by a HEADERS frame and purportedly continued by CONTINUATION frames) forces the server to allocate memory to store these incoming headers, awaiting the completion of the header block.
- As more and more CONTINUATION frames are received without the
END_HEADERS
flag, the server’s memory usage increases. This is compounded by the server’s anticipation of additional headers, preventing it from freeing up the allocated memory.
- Server Overload:
- The continued receipt of these incomplete header streams leads to excessive memory consumption. The server becomes slower as it juggles its resources between maintaining these incomplete streams and handling legitimate user requests.
- Eventually, the server may exhaust its available memory or become so bogged down that it can no longer respond effectively to legitimate traffic, resulting in a DoS condition.
Comparison to previous HTTP/2 vulnerabilities
The CONTINUATION Flood Vulnerability in HTTP/2 is part of a broader landscape of vulnerabilities associated with this protocol. Comparing this specific vulnerability to previous HTTP/2 vulnerabilities provides insight into how the protocol’s features can be exploited and the evolving nature of security challenges in web communications. Here’s a comparison with some notable HTTP/2 vulnerabilities:
CONTINUATION Flood Vulnerability
- Nature: Exploits the handling of CONTINUATION frames in HTTP/2, which allow for extended header blocks across multiple frames.
- Impact: Can lead to denial of service (DoS) through resource exhaustion, specifically by consuming server memory and CPU as it waits for the completion of header blocks that never end.
- Detection Difficulty: Hard to detect because the incomplete requests may not be logged traditionally, since they never form a complete HTTP request.
- Mitigation: Implementing timeouts and size limits on headers, improving anomaly detection for unusual header patterns, and ensuring incomplete sessions are logged for analysis.
Previous HTTP/2 Vulnerabilities
- HPACK Bomb:
- Nature: Involves creating a compression bomb using HPACK compression, where a small message decompresses to an unreasonably large size, consuming excessive server resources.
- Impact: Similar to the Zip Bomb in traditional file systems, leading to DoS by filling up the server’s memory with decompressed header information.
- Detection Difficulty: Relatively easier to detect as the anomaly in data sizes is substantial.
- Mitigation: Limiting the maximum size of the decompressed headers and monitoring the ratio of compressed to decompressed sizes.
- Dependency Cycle Attack:
- Nature: Exploits the stream dependency features in HTTP/2, where an attacker crafts requests that create circular dependencies, causing the server to wait indefinitely for resolutions that never materialize.
- Impact: Leads to server deadlock situations where legitimate requests are stalled, resulting in service degradation or DoS.
- Detection Difficulty: More complex to detect due to the logical nature of the dependency definition.
- Mitigation: Validation of dependency chains to detect and break cycles, along with enhanced server configurations to handle dependency resolution more robustly.
- Stream Multiplexing Abuse:
- Nature: Involves the improper or malicious use of HTTP/2’s multiplexing capabilities, where numerous idle or slow streams are opened without legitimate purpose.
- Impact: Can exhaust server resources and complicate management of valid streams, potentially leading to DoS.
- Detection Difficulty: Detecting abuse can be challenging as it involves distinguishing between high levels of legitimate and illegitimate use of multiplexing.
- Mitigation: Implementing limits on the number of concurrent streams, and monitoring the health and activity level of each stream.
The Real-World Impact
The implications are severe—ranging from crashed servers causing direct outages to subtler performance degradations that can still deny services effectively. Particularly alarming is the attack’s ability to be executed from a single machine, or even a single TCP connection, depending on the server’s configuration and defenses.
Mitigation Strategies
Effective defenses against the CONTINUATION Flood include:
- Setting Time and Size Limits: Implementing strict timeouts for header processing and limiting the size of header blocks can prevent attackers from exploiting this vulnerability.
- Enhanced Monitoring: Servers need to be equipped with tools that can detect anomalies in header size and frame sequencing.
- Robust Logging Practices: Improving log coverage to include all incoming requests, regardless of their completion status, will aid in identifying attack patterns and origins.
As HTTP/2 continues to be adopted widely across the internet, understanding and mitigating its vulnerabilities is paramount. The CONTINUATION Flood serves as a stark reminder of the continuous arms race in cybersecurity. Vigilance and advanced protective measures are essential to safeguard against such vulnerabilities that not only threaten individual servers but, potentially, the very infrastructure of the web.
This detailed exposition not only highlights the need for immediate attention to securing HTTP/2 implementations but also provides crucial insights into how such attacks are structured and how they can be thwarted. As we move forward, the security community must remain ever vigilant against evolving cyber threats to keep our digital world secure.
Information security specialist, currently working as risk infrastructure specialist & investigator.
15 years of experience in risk and control process, security audit support, business continuity design and support, workgroup management and information security standards.