Shin x Blog

PHPをメインにWebシステムを開発してます。Webシステム開発チームの技術サポートも行っています。

PHPにおけるhttpoxyの対応

HTTP リクエストに任意の値をセットすることで、Web アプリケーションからの HTTP 通信を傍受したり、中間者攻撃(Man-in-the-Middle)を可能にする脆弱性が見つかっています。

専用サイト

httpoxyという名前が付けられ、専用サイトが立ち上がっています。詳細は、このサイトが詳しいです。

httpoxy.org

攻撃内容

  • アプリケーションからHTTP通信を行う際に、環境変数HTTP_PROXYの値を、HTTPプロキシとして見るライブラリがある。
  • HTTPリクエストにProxyヘッダを付けられると、環境変数HTTP_PROXYにその値がセットされる。(これは、CGIの仕様)
  • つまり、任意のプロキシを外部から指定できてしまうので、通信内容の傍受や偽装ができてしまう。

対象となる PHP アプリケーション

  • HTTP リクエストを受けて動作する PHP アプリケーション
  • アプリケーションから、HTTP 通信を行うもの
  • 利用している HTTP 通信を行うパッケージなりライブラリが、環境変数 HTTP_PROXY の値を HTTP プロキシとして扱う場合

対応方法

1 or 2 のいずれかの方法で対応します。

1. httpdサーバ(アプリケーション以前で)Proxyヘッダを落とす。

  • nginx

www.nginx.com

  • Apache(httpd)

https://www.apache.org/security/asf-httpoxy-response.txt

冒頭の専用サイトでは、Varnish や HAProxy などの対応方法も記載されている。

2. 環境変数HTTP_PROXYをHTTPプロキシとして利用しないようにする。

  • Guzzle

Guzzle がこれに該当していたので、修正版がリリースされている。Guzzle に依存するパッケージでは、6.2.1以上を使う。

Guzzle の対応コミットは以下。SAPIを確認して、cli以外では、HTTP_PROXYを利用しないようになっている。

github.com

Drupal が、Guzzle を利用しており、composer.json の依存バージョンを ~6.2 に変更している。Guzzle を利用したアプリケーションならこの対応が参考になる。

github.com

  • curl

curl は、10年以上前からこの問題を認識しており、大文字のHTTP_PROXYは見ないようにしていた。

Linux では、環境変数は case sensitive なので、HTTP_PROXYhttp_proxy は別ものとなる。

番外. PHP で、HTTP_PROXYの値を落とす対応はオススメしない

下記のようなPHPコードでの対応は、効果が無い *1 ので、上記 2 つでの対応が望ましい。

$_SERVER['HTTP_PROXY'] = ''; // 環境変数には効果無し
putenv('HTTP_PROXY=');       // ヘッダから来た値には無効
  • Using unset($_SERVER['HTTP_PROXY']) does not affect the value returned from getenv(), so is not an effective mitigation
  • Using putenv('HTTP_PROXY=') does not work either (to be precise: it only works if that value is coming from an actual environment variable rather than a header – so, it cannot be used for mitigation) https://httpoxy.org

追記1(2016/07/20)

getenv() は、SAPI ごとにハンドラを登録することができ、定義されていれば、そちらが優先される仕組みになっています。 github.com

例えば、php-fpm であれば、php-fpm 実行中は、fcgi env から値を取得するようになっています。 github.com

追記2(2016/07/20)

PHP 本体には、すでに修正コミットが入っています。

github.com

次のリリース(下記を見る限りは、2016/07/21)に含まれています。

github.com

追記3(2016/07/20)

RHEL / CentOS では、すでに httpd パッケージに修正版が出ています。Proxyヘッダの値を、環境変数HTTP_PROXYの値としてスクリプトに渡さなくなります。

CVE-2016-5387 - Red Hat Customer Portal

CentOS alert CESA-2016:1421 (httpd) [LWN.net] CentOS alert CESA-2016:1421 (httpd) [LWN.net] CentOS alert CESA-2016:1422 (httpd) [LWN.net]

追記4(2016/07/21)

httpoxy 対応版の PHP 7.0.9、5.6.24、5.5.38 がリリースされました。

http://jp2.php.net/downloads.php#v7.0.9

http://jp2.php.net/downloads.php#v5.6.24

http://jp2.php.net/downloads.php#v5.5.38

参考

blog.ichikaway.com

HTTPoxy - CGI "HTTP_PROXY" variable name clash - Red Hat Customer Portal

*1:$_SERVER['HTTP_PROXY']の値をプロキシとするライブラリがあれば効果はあるが...