What is HTTP/2 ?
HTTP/2 is an updated version of the HTTP protocol and was released in 2015. After the changes in HTTP specifications in 1999, this was the next major update that was issued for HTTP. HTTP/2 is based on SPDY protocol which is used in popular products like Google Chrome , Mozilla Firefox, Microsoft Internet Explorer, etc. HTTP/2 enables faster browsing and encryption capabilities.
Jonathan Looney of Netflix and Piotr Sikora of Google discovered a set of vulnerabilities in HTTP/2 that impact the availability of servers using HTTP/2 worldwide. According to W3Techs, 40% of the websites on the internet use HTTP/2.
What causes these security holes in HTTP/2?
RFC7540 has outlined a few general security considerations for denial of service condition in HTTP/2. The recently discovered vulnerabilities do not fall in the scope of the security considerations discussed by RFC7540.
HTTP/2 uses header compression which requires a strict commitment of resources compared to HTTP/1.1.The attack vectors for the vulnerabilities discovered in HTTP/2 follow a certain pattern. The main goal is to setup a queue of responses to exhaust the resources on a server. A malicious client asks the server to return responses to certain requests. These responses are not read by the client and build up in a queue. The efficiency of queue handling in a server decides how much CPU and/or memory resources are consumed in such a situation. Excessive usage of the resources leads to a crash.
These attacks are designed to work at the HTTP/2 transport layer. This layer lacks a systematic tooling to log, rate-limit, and trigger remediation corresponding to the client’s behavior at the HTTP/2 connection layer.
The HTTP/2 vulnerabilities impact only the availability of servers and do not allow an attacker to leak or modify information.
Attack Vectors in servers that support HTTP/2 communication
The following CVEs outline the various methodologies to exhaust the CPU and memory resources, thereby causing a crash or denial of service condition:
- CVE-2019-9511 (Data Dribble) : An attacker can make a request to the server to return huge amounts of data from a specified resource over multiple streams. The server is forced to queue the data in 1byte chunks by manipulating the window size and stream priority. At this point, there is an excessive consumption in the memory and/or CPU usage depending on the efficiency of the server to handle queues.
- CVE-2019-9512 (Ping Flood): An internal queue of responses can be built up by sending continual pings to an HTTP/2 peer. Depending on how efficiently this data is queued, different amounts of CPU and memory resources are utilized. Excessive consumption leads to denial of service.
- CVE-2019-9513 (Resource Loop): An attacker creates multiple request streams and shuffles the priority of the streams continuously. This causes a substantial churn to the priority tree which can lead to excessive CPU consumption and then a crash.
- CVE-2019-9514 (Reset Flood) : An attacker sends invalid requests over multiple streams in expectation of receiving RST_STREAM frames from the peer. RST_STREAM frames are returned in HTTP/2 when a client aborts the request made while still keeping the connection open. Depending on the handling of RST_STREAM frames in queue, different amounts of CPU and memory resources are consumed. Excessive consumption leads to denial of service.
- CVE-2019-9515 (Settings Flood) : RFC specifies that the peer should reply with one acknowledgement for every SETTINGS frame. An attacker can abuse this functionality by sending a stream of SETTINGS frames to the peer. Depending on the efficiency in handling the data, different amounts of CPU and/or memory resources are consumed. Excessive consumption leads to denial of service.
- CVE-2019-9516 (0-Length Headers Leak) : Some implementations allocate a certain memory for request headers and keep them intact until the session expires. An attacker can abuse this functionality by sending a stream of headers with a 0-length header name and 0-length header value with size of 1-byte or greater. This can consume excess memory and lead to denial of service condition.
- CVE-2019-9517 (Internal Data Buffering) : An attacker opens an HTTP/2 window and closes a TCP window. Sending a stream of requests for a large response object results in excess memory consumption and a crash. This happens because, opening an HTTP/2 window allows the peer to send without limitations but does not allow it to write bytes on the wire. This builds up a queue of responses and excess memory consumption which leads to denial of service.
- CVE-2019-9518 (Empty Frames Flood) : An attacker sends a stream of frames (DATA, HEADERS, CONTINUATION and/or PUSH_PROMISE) without the flag which indicates the end of stream. The peer processes every frame disproportionate to attack bandwidth leading to excessive CPU consumption. This causes denial of service.
Cloudflare reported that some attacks have been observed in the wild. It is highly recommended to install the updates available from vendors.
All servers that support HTTP/2 communication are affected. An extensive list of vendors affected by this vulnerability can be found here. It is important to note that not all products are affected by all the vulnerabilities. The respective vendors have published information about the vulnerabilities related to their products in the advisories.
Successful exploitation of these vulnerabilities leads to Denial of Service condition. Some of them enable a single-end system to disrupt the service on multiple servers.
Many vendors including Cloudflare, Microsoft(CVE-2019-9511, CVE-2019-9512, CVE-2019-9513, CVE-2019-9514, CVE-2019-9518), Apple(SwiftNIO), NGINX, Nodejs, Ubuntu released updates to mitigate these vulnerabilities. Apache released an advisory stating that Tomcat is not affected by the DoS vulnerabilities. But, the subsequent versions would be handling abusive client behaviour. Updates were also released for Google Go . Synology has mentioned the list of products affected in an advisory, but has not released updates so far.
Netflix suggests that a possible workaround is to disable the HTTP/2 support. They have also warned that might cause a degradation in the performance and might not be possible in all cases.