CVE-2020-11100 haproxy: 不適切な形式の HTTP/2 リクエストによる境界外書き込み (out-of-bounds writes) の可能性
エグゼクティブサマリー
Red Hat は、特定の HTTP/2 リクエストパケットが HAProxy によって処理される方法に不具合があることを認識しています。 攻撃者は、メモリー破損の原因となる悪意を持って作成された HTTP/2 リクエストパケットを送信することでクラッシュを発生することが可能になり、HAProxy を実行しているユーザーの権限を使用して任意コードのリモート実行が可能になります。
この問題には、セキュリティー上の影響度が「重大な影響」の「CVE-2020-11100 」が割り当てられました。
影響を受ける製品
CVE-2020-11100 の影響を受ける Red Hat の製品
製品/パッケージ | 影響状態 |
Red Hat Enterprise Linux 6 (haproxy) | 影響なし |
Red Hat Enterprise Linux 7 (haproxy) | 影響なし |
Red Hat Enterprise Linux 7 Software Collections (rh-haproxy18-haproxy) | 影響あり: アクティブなストリームを修正予定 (Will Fix) |
Red Hat Enterprise Linux 8 (haproxy) | 影響あり: アクティブなストリームを修正予定 (Will Fix) |
Red Hat OpenStack Platform 10 (openstack-haproxy-container) | 影響なし: RHEL 7 パッケージを使用 |
Red Hat OpenStack Platform 13 (openstack-haproxy-container) | 影響なし: RHEL 7 パッケージを使用 |
Red Hat OpenStack Platform 15 (openstack-haproxy-container) | 影響あり: RHEL8 パッケージを使用 |
Red Hat OpenStack Platform 16 (openstack-haproxy-container) | 影響あり: RHEL8 パッケージを使用 |
Red Hat OpenShift Container Platform 3.11 | 影響あり: 修正予定 (Will Fix) |
Red Hat OpenShift Container Platform 4 | 影響あり: 低い影響度 (Low Severity) |
影響を受ける製品の更新
製品名 | パッケージ | アドバイザリー/更新 |
Red Hat Enterprise Linux 8 | haproxy | RHSA-2020:1288 |
Red Hat Enterprise Linux 8 Update Services for SAP Solutions | haproxy | RHSA-2020:1289 |
Red Hat Software Collections | rh-haproxy18-haproxy | RHSA-2020:1290 |
Red Hat OpenShift Container Plafform 3.11 | haproxy | 更新保留中のリリース |
Red Hat OpenStack Container Plafform (影響を受けるバージョン) | openstack-haproxy-container | 更新は Container Catalog から入手可能 |
技術的な詳細と背景
HAProxy は、高可用性環境向けの TCP/HTTP リバースプロキシーです。 HAProxy は通常、アプリケーションサーバーのクラスターの前にデプロイされ、サーバーの 1 つに受信リクエストをディスパッチします。そのため、パフォーマンスや高可用性が向上されます。 HAProxy が Web サイトとデプロイされた場合、ネットワークリソースをより効率的に使用するために任意で HTTP/2 プロトコルを使用することができます。
HTTP/2 リクエストパケットが HAProxy によって処理される方法に不具合が存在します。
Red Hat Enterprise Linux 6 および 7 に同梱される HAProxy パッケージには、HTTP/2 のサポートが含まれないため、この不具合の影響を受けません。
OpenShift Container Platform 4 は、4.3 までのすべてのバージョンに脆弱なコードが含まれます。しかし、この不具合を悪用するには、OpenShift の Ingress Operator に ROUTER_USE_HTTP2 を設定する必要があり、この設定は現在不可能です。よって、OCP 4.x の 4.4 未満のバージョンでは、この脆弱性の影響度は低くなります。
OpenShift Container Platform 3.11 には、HTTP/2 のサポートを簡単に有効化できる 設定オプションが ose-haproxy-router に追加されています。しかし、このバージョンのデフォルト設定では有効になっていません。
軽減策
影響を受ける製品のセキュリティーエラータはできる限り早くリリースされます。詳細は上記の表を参照してください。修正がリリースされる前に解決策が必要なお客様や、他の解決策が必要なお客様は、次に説明する軽減策の適用をご検討ください。
Red Hat Enterprise Linux 8 では、HAProxy は SELinux によって制限されるため、任意コードのリモート実行の可能性は軽減されると考えられます。
この問題は、HTTP/2 プロトコルのサポートを無効にすることで軽減できます。Red Hat 製品に同梱されるデフォルトの HAProxy 設定では HTTP/2 が無効になっていますが、お客様の環境に合わせてデフォルト設定を変更するのは一般的です。
HTTP/2 の設定を確認するには、HAProxy 設定ファイルで「h2」が含まれる行を探します。 通常、この行は次のようになります。
bind :443 ssl crt pub.pem alpn h2,http/1.1
OpenShift Container Platform 3.11 でこの脆弱性を軽減するには、デフォルト設定を変更せずに HTTP/2 を無効のままにするか、以前有効にした場合は無効にします。
また、以下のように curl コマンドラインツールを使用して、HTTP/2 のサポートが指定のサーバーで有効になっているかどうかを確認することもできます。 どちらの場合でも、クライアントは HTTP/2 を提供しますが、サーバーは最初の場合でのみ HTTP/2 を許可することに注目してください。 ホスト名は適切な名前に置き換えてください。
$ 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
** バックエンドサーバーによって HTTP/2 応答が提供され、HAProxy ではパススルーモードが使用されている場合、このテストの結果では HTTP/2 が使用されていると示されるため、注意してください。 このテストの結果が否定的 (server did not agree to a protocol) である場合は、結果を信用できます。 結果が肯定的である場合 (server accepted to use h2) 、設定を詳細に調査し、応答が受信される場所の詳細を確認する必要がある場合があります。 結果が肯定的 (server accepted to use h2) でも、HTTP/2 が使用されていないと思われる場合は、ルート設定でパススルーモードを確認してください。
OpenShift Container Platform 3.11 のテストに適した URL は、パススルールートを使用しない openshift-console プロジェクトの Cluster Console です。このルートは、ルーター Pod によってプロキシー化されない openshift-web-console プロジェクトの Application Console とは異なります。
$ 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
パススルールートの例として、OpenShift Container Platform 3.11 の API サーバーが挙げられます。 これは haproxy の背後になりますが、パススルーであるため、HTTP/2 が有効になっている Go 言語バイナリーの Pod 内部で接続が終了されます。 この場合、検出されるサーバーは apiserver Pod の内部にあり、ルーター Pod の脆弱な haproxy ではありません。
$ 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
謝辞
Red Hat は、本問題を報告した HAProxy プロジェクトに感謝します。アップストリームは、本問題の最初の報告者が Google Project Zero の Felix Wilhelm 氏であることを認識しています。
Comments