HAProxy の深刻な脆弱性により HTTP リクエスト・スマグリングが生じる?

HAProxy Found Vulnerable to Critical HTTP Request Smuggling Attack

2021/09/08 TheHackerNews — HAProxy は、オープンソースのロード・バランサー/プロキシ・サーバーとして広く利用されているが、この HAProxy には深刻なセキュリティ上の脆弱性が存在する。この CVE-2021-40346として追跡されている整数オーバーフローの脆弱性は、CVSS 値 8.6 であり、HAProxy Ver 2.0.25 / 2.2.17 / 2.3.14 / 2.4.4 で修正されている。

HTTP Request Smuggling とは、その名 (密輸) の通り、複数のユーザーから受信した一連の HTTP リクエストを、Webサイトが処理する方法を改ざんする、Web アプリケーション攻撃の1つである。この HTTP 非同期化とも呼ばれる手法は、フロントエンド・サーバーとバックエンド・サーバーがリク エストを処理する際の、解析上の不整合を悪用するものである。

フロントエンド・サーバーとは、単一の接続を介してインバウンド HTTP リクエストのチェーンを管理し、それらを単数/複数のバックエンド・サーバーに転送するために、Web サイトで用いられるロード・バランサーまたはリバース・プロキシのことである。したがって、サーバーが1つのリクエスト処理を終了したとき、次のリクエストが始まる場所を判別できるよう、リクエストの両端で正しく処理することが重要となる。これに失敗すると、あるリクエストに追加された悪意のコンテンツが、次のリクエストの先頭に追加されるというシナリオが発生する可能性がある。

つまり、フロントエンドとバックエンドのサーバーが Content-Length ヘッダーと Transfer-Encoding ヘッダーを使用して各リクエストの開始と終了を判断する仕組みに問題があり、不正な HTTP リクエストの終了が誤って計算され、悪意のあるコンテンツがあるサーバーでは処理されずに、連鎖的に次の受信リクエストの先頭に付加されてしまう。

具体的に言うと、フロントエンド・サーバーとバックエンド・サーバーが、Content-Length ヘッダーと Transfer-Encodingヘッダーを使用して、各リクエストの開始と終了を処理する方法に問題が生じると、不正な HTTP リクエストの終了が誤って計算される。この場合、悪意のコンテンツは1サーバーでは処理されず、チェーン内の次のインバウンド・リクエストの先頭に、プレフィックスが付けられた状態になってしまう。

JFrog Security の研究者たちは、火曜日に発表したレポートの中で、「この攻撃は、整数オーバーフローの脆弱性を利用することで、HAProxy が HTTP リクエストを解析している間に、とりわけ Content-Length ヘッダーを処理するロジックにおいて、予期せぬ状態に到達する可能性が生じる。この脆弱性は、悪意のリクエストをブロックするためのカスタム・ルールを定義する、HAProxy の ACL (Access Control List) ルールを回避することを目的とした、HTTP Request Smuggling 攻撃に使用される可能性がある。

HAProxy は、この問題を解決するために、名前と値の長さをチェックする機能を追加した。HAProxy の開発者である Willy Tarreau は、9月3日に公開された GitHub のコミットで、「緩和策としては、そのような [content-length] ヘッダーが、メッセージに1つしか存在しないことを確認すれば十分だ」と述べている。上記のバージョンにアップグレードできない顧客は、攻撃を緩和するために、プロキシのコンフィグレーションに、以下のスニペットを追加することを推奨する。

http-request deny if { req.hdr_cnt(content-length) gt 1 }
http-response deny if { res.hdr_cnt(content-length) gt 1 }

この脆弱化 CVE-2021-40346 ですが、Ubuntu と Debian に含まれる HAProxy として、それぞれのベンダーから情報が出ていました。まだ、NVD は追いついていないようで、詳しい情報も得られていません。なお、HTTP リクエスト・スマグリングに関しては、Qiita の「HTTP Request Smuggling を理解する」で詳しく解説されていますので、そちらを ご参照ください。