CVE-2020-11100 haproxy: malformed HTTP/2 requests can lead to out-of-bounds writes

Public Date: April 1, 2020, 21:20
Updated September 3, 2021, 12:09 - Chinese, Simplified Japanese Korean
Resolved Status
Critical Impact

Insights vulnerability analysis

View exposed systems

Executive Summary

Red Hat is aware of a flaw in the way HAProxy processed certain HTTP/2 request packets.  An attacker could send crafted HTTP/2 request packets which cause memory corruption, leading to a crash or remote arbitrary code execution with the permissions of the user running HAProxy. 

This issue has been assigned CVE-2020-11100 with a severity impact of Critical.

Affected Products

Red Hat Products Affected by CVE-2020-11100

Product/PackageAffected State
Red Hat Enterprise Linux 6 (haproxy)Not Affected
Red Hat Enterprise Linux 7 (haproxy)Not Affected
Red Hat Enterprise Linux 7 Software Collections (rh-haproxy18-haproxy)Affected - Will Fix active streams
Red Hat Enterprise Linux 8 (haproxy)Affected - Will Fix active streams
Red Hat OpenStack Platform 10 (openstack-haproxy-container)Not Affected - uses RHEL 7 package
Red Hat OpenStack Platform 13 (openstack-haproxy-container)Not Affected - uses RHEL 7 package
Red Hat OpenStack Platform 15 (openstack-haproxy-container)Affected - uses RH:EL 8 package
Red Hat OpenStack Platform 15 (openstack-neutron-base-container)Affected - uses RH:EL 8 package
Red Hat OpenStack Platform 16 (openstack-haproxy-container)Affected - uses RH:EL 8 package
Red Hat OpenStack Platform 16 (openstack-neutron-base-container)Affected - uses RH:EL 8 package
Red Hat OpenShift Container Platform 3.11Affected - Will Fix
Red Hat OpenShift Container Platform 4Affected - Low Severity

Updates for Affected Products

ProductPackageAdvisory/Update
Red Hat Enterprise Linux 8haproxyRHSA-2020:1288
Red Hat Enterprise Linux 8 Update Services for SAP SolutionshaproxyRHSA-2020:1289
Red Hat Software Collectionsrh-haproxy18-haproxyRHSA-2020:1290
Red Hat OpenShift Container Platform 3.11haproxyRHSA-2020:1287
Red Hat OpenStack Platform 15openstack-haproxy-containerRHBA-2020:1328
Red Hat OpenStack Platform 15openstack-neutron-base-containerUpdates available in the Container Catalog
Red Hat OpenStack Platform 16openstack-haproxy-containerRHBA-2020:1327
Red Hat OpenStack Platform 16openstack-neutron-base-containerUpdates available in the Container Catalog


Technical Details and Background

HAProxy is a TCP/HTTP reverse proxy which is designed for high availability environments.  HAProxy is typically deployed in front of a cluster of application servers and dispatches incoming requests to one of the servers, resulting in increased performance and high availability.  When deployed with a website, HAProxy can optionally use the HTTP/2 protocol for more efficient use of network resources.

This is a flaw in the way HTTP/2 request packets are handled by HAProxy. 

HAProxy packages shipped with Red Hat Enterprise Linux 6 and 7 do not contain support for HTTP/2; therefore, they are not affected by this flaw.

All OpenShift Container Platform 4 versions through 4.3 contain the vulnerable code. However, exploitation requires setting ROUTER_USE_HTTP2 in the OpenShift Ingress Operator, which is not currently possible. The impact of this vulnerability, is therefore, reduced in OCP 4.x before version 4.4 to low.

OpenShift Container Platform 3.11 added a configuration option to ose-haproxy-router that made enabling HTTP/2 support easy. However, it is not enabled by default on that version.

Mitigation

Security errata for affected products are released as early as possible; please consult the table above for availability details. Customers requiring a solution before fixes are available, or seeking an alternative solution, should assess the mitigation described below.

On Red Hat Enterprise Linux 8, HAProxy is confined by SELinux, which should mitigate remote arbitrary code execution.  

This issue can be mitigated by not enabling support for HTTP/2 protocol. The default HAProxy configurations shipped with Red Hat products have HTTP/2 disabled, but it is common to alter these defaults in a customer environment.

You can check if HTTP/2 is enabled by searching your HAProxy configuration files for a line containing 'h2'.  Typically this looks something like:
    bind :443 ssl crt pub.pem alpn h2,http/1.1

To mitigate this vulnerability in OpenShift Container Platform 3.11, keep HTTP/2 disabled as it is by default, or disable if you have it previously enabled.

You can also verify if HTTP/2 support is enabled on a given server using the curl command line tool as follows.  Note that in both cases, the client offers HTTP/2, but the server only accepts it in the first case.  Replace the hostname with your own.

$ curl -v --http2 https://h2-enabled.example.com/ 2>&1 >/dev/null | grep ALPN 
* ALPN, offering h2
* ALPN, offering http/1.1
* ALPN, server accepted to use h2

$ curl -v --http2 https://h2-not-enabled.example.com/ 2>&1 >/dev/null | grep ALPN
* ALPN, offering h2
* ALPN, offering http/1.1
* ALPN, server did not agree to a protocol

** Note that if the backend server is serving HTTP/2 responses and HAProxy is using passthrough mode, this test will show HTTP/2 in use.  A negative result from this test can be relied on.  A positive test may need to be confirmed by ensuring a closer examination of the configuration to confirm more specifics of where the response is being received.  If you get a positive result and you think you’re not using HTTP/2, check the route configuration for passthrough mode.

A good URL to test for OpenShift Container Platform 3.11 is the “Cluster Console” (in the openshift-console project) because it doesn’t use a passthrough route. Note that this route is distinct from the “Application Console” (in the openshift-web-console project), which isn't proxied by the router pod.

$ curl -v --http2 https://console.apps.example.com 2>&1 >/dev/null | grep ALPN
* ALPN, offering h2
* ALPN, offering http/1.1
* ALPN, server did not agree to a protocol

The API server in OpenShift Container Platform 3.11 is an example of a pass through route.  Even though this is behind haproxy, the fact it’s a passthrough means the connection terminates inside the pod in a golang binary that has HTTP/2 enabled.  The server detected in this case is inside the apiserver pod, and not the vulnerable haproxy in the router pod.

$ curl -v --http2 https://apiserver-kube-service-catalog.apps.example.com 2>&1 >/dev/null | grep ALPN
* ALPN, offering h2
* ALPN, offering http/1.1
* ALPN, server did not agree to a protocol

Acknowledgements

Red Hat thanks the HAProxy project for reporting this issue. Upstream acknowledges Felix Wilhelm from Google Project Zero as the original reporter of this issue.

References

Google Project Zero Disclosure

Google Project Zero 

HAProxy team blog

Comments