PHP 5.6.38他で修正された任意コンテンツ送信脆弱性について

Computer, Security 9月 20, 2018 #PHP, #脆弱性
(Last Updated On: 2018年10月3日)

PHP 5.6.38/7.0.32/7.1.22/7.2.10でApache2handler SAPIのセキュリティバグが修正されました。

13 Sep 2018
Apache2:

Fixed bug #76582 (XSS due to the header Transfer-Encoding: chunked).

http://php.net/ChangeLog-5.php#5.6.38

攻撃者が送った出鱈目な攻撃用データがPHPプログラムに関係なくブラウザに出力されてしまう問題が修正されました。

この脆弱性の影響が正しく伝わっていないようなので、簡単に紹介します。

PHP5.6.38リリース対応 PHPセキュリティ保守サービス にも記載されている通りです。

この脆弱性を攻撃するにはPOSTリクエストがキャッシュされる必要があります。通常、プロキシサーバーはPOSTリクエストをキャッシュしません。PHPのメモリバッファではなく、Apache httpdサーバーのメモリバッファに残った不正なデータが送信されるため、PHPのob_start()などを使った出力バッファでキャッシュを行った場合もキャッシュされません。このため、脆弱性の説明から感じられる危険性ほど大きなリスクはありません。ただし、何らかの理由でPOSTリクエストもプロキシサーバーでキャッシュしている場合の影響は致命的です。

正常なChunked EncodingのPOSTデータは正しく処理され、余計な出力は行われません。

攻撃者が攻撃用ツールなどで壊れたChunked EncodingのPOSTリクエストを送信(送信先のURL/スクリプトは問わない、Apache2handelr+PHPで処理さえされていればよい)すると、PHPのApache2handler SAPIが処理しないデータがApache httpdのバッファに残り、その内容がクライアントに送信されてしまうのがこの脆弱性です。

Apache2handler+PHPのサーバーが直接クライアントに接続する構成の場合、攻撃者は攻撃者自身しか攻撃できないことになります。

壊れたChunked EncodingのPOSTデータが必要なので、リクエストはPOSTメソッドになります。このため、一般的な設定のリバースプロキシ/プロキシにはキャッシュされません。つまり一般的な構成のシステムではプロキシキャッシュ汚染を利用した、他のユーザーへの攻撃は行なえません。

PHPの出力バッファ(ob_start関数など)でmemcachedやredis、ファイルなどにキャッシュしている場合も、壊れたPOSTデータコンテンツがPHPから見えないためキャッシュできません。もし、見えてしまうケースがあったとしても、キッチリ作ってあるアプリケーションならPHPから見える入力データは全てバリデーション&エスケープされているハズです。攻撃者の任意のコンテンツ(JavaScriptなど)を危険な状態で送信&キャッシュしてしまう状態はセキュアな状態のアプリケーションではないハズです。従って、PHPによるキャッシュを利用した他のユーザーへの攻撃も行なえません。

攻撃者が送った出鱈目な攻撃用データがPHPプログラムに関係なくブラウザに出力されてしまう、と聞くとかなり危険な脆弱性に聞こえてしまいます。しかし、実際には影響を受けるシステムは限定的だと考えられます。

とは言っても攻撃可能な構成の設定もあり得ます。もしかすると攻撃用の壊れたデータバッファーがそのまま出力されてしまう動作、を現在のところ認識されていない方法で悪用することが可能かも知れません。できるだけ早くアップグレードする方が良いでしょう。

※ もしGETリクエストでも攻撃できる場合は致命的です。
※ この脆弱性は少なくともPHP 4.4から存在します。
※ Apacheのmod_cacheはキャッシュしてしまうようです。ご注意ください。

投稿者: yohgaki