HTTPoxyとは何ですか?

2016年7月18日、HTTPoxyと呼ばれるCGIアプリケーションの脆弱性が公開されました。 攻撃者は、リクエストとともにHTTP Proxyヘッダーを渡すことにより、脆弱な展開を悪用する可能性があります。これにより、バッキングサービスに接続するときにアプリケーションが使用するURLが変更されます。 これは、資格情報の漏洩、アプリケーションへの応答の変更などに使用できます。

この脆弱性は、バックエンドプロキシサービスの場所を指定するために頻繁に使用されるHTTP_PROXY環境変数とProxyHTTPクライアントヘッダーの間の名前の衝突によって引き起こされます。 CGI仕様では、名前空間にHTTP_プレフィックスを付けて、クライアント提供のヘッダーを環境に渡す必要があります。 このマングリングは、HTTP_PROXYなどの構成変数と衝突します。これらの変数もHTTP_で始まります。 CGIアプリケーションまたはライブラリが追加の処理なしでこの変数を使用する場合、プロキシサービスへの接続を試行するときに、クライアントによって提供された値を使用することになります。

この脆弱性はさまざまなCGIのような実装に影響を与えるため、 CVE-2016-5386 CVE-2016-5386 CVEのセキュリティ脆弱性識別子が多数作成されています。 -2016-5387 CVE-2016-5388 CVE-2016-1000109 、および CVE-2016-1000110 (この時点で書き込み中、これらは予約されていますが、記入されていません)。

HTTPoxyの脆弱性は、2001年以降、いくつかの形式で知られていますが、最近まで広範囲に及ぶ問題として認識されることはありませんでした。 多くの展開に影響を与える可能性がありますが、軽減は非常に単純で簡単です。

脆弱なサーバーとアプリケーション

HTTPoxyは、多くのCGI実装に見られる一般的な脆弱性です。 アプリケーションまたはサーバーはCGI仕様を正しく実装できますが、それでも脆弱です。

デプロイメントが脆弱であるためには、次のことを行う必要があります。

  • HTTP_PROXY環境変数を使用してプロキシ接続を構成します:アプリケーションコード自体または使用されるライブラリのいずれかで活用します。 これは、環境を使用してプロキシサーバーを構成するためのかなり標準的な方法です。
  • HTTP を使用してバックエンドサービスにリクエストを送信:名前の衝突はHTTP_プレフィックスに固有であるため、HTTPを使用してアプリケーションによって作成されたリクエストのみが影響を受けます。 HTTPSまたはその他のプロトコルを使用するリクエストは脆弱ではありません。
  • CGIまたはCGIのような環境で動作する:クライアントヘッダーがHTTP_プレフィックス付き環境変数に変換される展開は脆弱です。 CGIまたはFastCGIなどの関連プロトコルの準拠実装はこれを行います。

ご覧のとおり、デプロイメントが脆弱になるには、デプロイメント固有の要素とアプリケーション固有の要素の組み合わせが必要です。 展開が影響を受けるかどうかをテストするために、 Luke Rehmann は、一般にアクセス可能なサイトの脆弱性をチェックするための単純なサイトを作成しました

言語固有の情報

CGIのようなデプロイメントは、他の言語よりもPHPエコシステムではるかに一般的であるため、特にPHPアプリケーションを監査する必要があります。 さらに、一般的なライブラリでgetenvメソッドが広く使用されているため、この問題が増幅されます。これは、構成変数だけでなく、サニタイズされていないユーザー入力を返すかどうかがすぐにはわからないためです。 現在影響を受けている特定のライブラリは、Guzzle(バージョン4.0.0rc2以降)、Artax、およびComposerのStreamContextBuilderクラスです。

CGIを使用してデプロイしたときに脆弱であることが判明した他の言語は、PythonとGoでした。 これらの言語は、他の脆弱性のない方法を使用してより一般的に展開されます。 ただし、CGIが使用されている場合、動作を変更せずにHTTP_PROXY変数を単純に読み取るライブラリは脆弱です。

脆弱性を打ち負かす方法

幸い、HTTPoxyの修正は比較的簡単です。 この脆弱性は、Webサーバーレイヤーまたはアプリケーションまたはライブラリから対処できます。

  • アプリケーションまたはライブラリは、CGI環境にある場合、HTTP_PROXY変数を無視できます。
  • アプリケーションまたはライブラリは、異なる環境変数を使用してプロキシ接続を構成できます
  • Webサーバーまたはプロキシは、クライアント要求で受信したProxyヘッダーの設定を解除できます

脆弱なライブラリを使用している場合は、問題に対処するためのパッチが利用可能になるまで、サーバー側の脅威を軽減する必要があります。 ライブラリまたはアプリケーションの作成者であり、プロジェクトがHTTP_PROXY変数に依存してプロキシバックエンドを構成している場合は、CGIのような環境で実行しているときに衝突しない代替変数の使用を検討してください。 Rubyや他のいくつかのプロジェクトでは、この目的でCGI_HTTP_PROXYを使用しています。

Proxyヘッダーは標準のHTTPヘッダーではないため、ほとんどの場合、無視しても問題ありません。 これは、アプリケーション自体にリクエストを送信するために使用されるWebサーバーまたはロードバランサーで実行できます。 Proxy HTTPヘッダーには標準的な正当な目的がないため、ほとんどの場合、削除できます。

一般的なWebサーバー、ロードバランサー、またはプロキシは、適切なヘッダーの設定を解除できます。

ApacheでHTTPプロキシヘッダーを削除する

Apache HTTP Webサーバーを実行している場合は、mod_headersモジュールを使用して、すべての要求のヘッダーの設定を解除できます。

UbuntuおよびDebianサーバー

UbuntuまたはDebianサーバーでmod_headersを有効にするには、次のように入力します。

  1. sudo a2enmod headers

その後、グローバル構成ファイルを開きます。

  1. sudo nano /etc/apache2/apache2.conf

下部に向かって、以下を追加します。

/etc/apache2/apache2.conf
. . .
RequestHeader unset Proxy early

ファイルを保存して閉じます。

構文エラーがないか構成を確認してください。

  1. sudo apache2ctl configtest

構文エラーが報告されない場合は、サービスを再起動します。

  1. sudo service apache2 restart

CentOSおよびFedoraサーバー

mod_headersモジュールは、従来のインストールではデフォルトで有効になっている必要があります。 Proxyヘッダーの設定を解除するには、グローバル構成ファイルを開きます。

  1. sudo nano /etc/httpd/conf/httpd.conf

下部に向かって、以下を追加します。

/etc/httpd/conf/httpd.conf
. . .
RequestHeader unset Proxy early

終了したら、ファイルを保存して閉じます。

次のように入力して、構文エラーを確認します。

  1. sudo apachectl configtest

構文エラーが報告されない場合は、次のように入力してサービスを再起動します。

  1. sudo service httpd restart

Nginxを使用したHTTPプロキシヘッダーの削除

Nginxでは、軽減は同様に簡単です。 サーバーまたはアップストリームで実行されているCGIのような環境の環境を簡単にサニタイズできます。

UbuntuおよびDebianサーバー

UbuntuおよびDebianサーバーでは、FastCGIプロキシを設定するときに、FastCGIパラメータは通常fastcgi_paramsまたはfastcgi.confファイルのいずれかから含まれます。 次の両方のファイルでHTTP_PROXYヘッダーの設定を解除できます。

  1. echo 'fastcgi_param HTTP_PROXY "";' | sudo tee -a /etc/nginx/fastcgi.conf
  2. echo 'fastcgi_param HTTP_PROXY "";' | sudo tee -a /etc/nginx/fastcgi_params

FastCGIプロキシを構成するときにファイルの1つを調達していない場合は、プロキシの場所自体にこの同じ行を含めるようにしてください。

/etc/nginx/sites-enabled/some_site.conf
. . .
    location ~ \.php$ {
        . . .
        fastcgi_param HTTP_PROXY "";
        . . .
    }
}

従来のHTTPプロキシにNginxを使用している場合は、HTTPProxyヘッダーもクリアする必要があります。 HTTPプロキシヘッダーは/etc/nginx/proxy_paramsファイルに設定されています。 次のように入力して、Proxyヘッダーの設定を解除するルールをそのファイルに追加できます。

  1. echo 'proxy_set_header Proxy "";' | sudo tee -a /etc/nginx/proxy_params

この場合も、サーバーブロック構成内からこのファイルを取得しない場合は、プロキシの場所自体にファイルを追加する必要があります。

/etc/nginx/sites-enabled/some_site.conf
. . .
    location /application/ {
        . . .
        proxy_pass http://127.0.0.1;
        proxy_set_header Proxy "";
        . . .
    }
}

次のように入力して、構文エラーを確認します。

  1. sudo nginx -t

エラーが報告されない場合は、サービスを再起動します。

  1. sudo service nginx restart

CentOSおよびFedoraサーバー

CentOSおよびFedora上のNginxも、同じfastcgi_paramsおよびfastcgi.confファイルを使用してFastCGIプロキシを構成します。 次のように入力して、これらのファイルの両方でHTTP_PROXYヘッダーの設定を解除します。

  1. echo 'fastcgi_param HTTP_PROXY "";' | sudo tee -a /etc/nginx/fastcgi.conf
  2. echo 'fastcgi_param HTTP_PROXY "";' | sudo tee -a /etc/nginx/fastcgi_params

FastCGIプロキシを構成するときにこれらのファイルのいずれかを調達していない場合は、プロキシの場所自体にこの同じ行を含めるようにしてください。

/etc/nginx/nginx.conf
. . .
    location ~ \.php$ {
        . . .
        fastcgi_param HTTP_PROXY "";
        . . .
    }
}

従来のHTTPプロキシにNginxを使用している場合は、HTTPProxyヘッダーもクリアする必要があります。 proxy_passを実行している任意の場所でProxyヘッダーの設定を解除するルールを追加する必要があります。 proxy_passが使用されている場所がわからない場合は、構成ディレクトリを簡単に検索できます。

  1. grep -r "proxy_pass" /etc/nginx
Output
/etc/nginx/nginx.conf.default: # proxy_pass http://127.0.0.1;

コメントアウトされていない結果(上記の例のように)は、proxy_set_header Proxy "";を含むように編集する必要があります。

/etc/nginx/nginx.conf
. . .
    location /application/ {
        . . .
        proxy_pass http://127.0.0.1;
        proxy_set_header Proxy "";
        . . .
    }
}

次のように入力して、構文エラーを確認します。

  1. sudo nginx -t

エラーが報告されない場合は、サービスを再起動します。

  1. sudo service nginx restart

HAProxyを使用したHTTPプロキシヘッダーの削除

HAProxyを使用してトラフィックをアプリケーションサーバーに転送している場合は、トラフィックを転送する前にProxyヘッダーを削除できます。

/etc/haproxy/haproxy.cfgファイルを開いて編集します。

  1. sudo nano /etc/haproxy/haproxy.cfg

http-requestディレクティブは、構成のfrontendbackend、またはlistenセクションで設定できます。

/etc/haproxy/haproxy.cfg
frontend www
    http-request del-header Proxy
    . . .

backend web-backend
    http-request del-header Proxy
    . . .

listen appname 0.0.0.0:80
    http-request del-header Proxy
    . . .

これらは各セクションで設定する必要はありませんが、含めることで問題はありません。 終了したら、ファイルを保存して閉じます。

次のように入力して構文を確認します。

  1. sudo haproxy -c -f /etc/haproxy/haproxy.cfg

問題が見つからない場合は、次のように入力してサービスを再起動します。

  1. sudo service haproxy restart

結論

HTTPoxyの脆弱性はかなり長い間公開されており、Web上にデプロイされた多数のアプリケーションに影響を与える可能性があります。 幸いなことに、任意のWebサーバーに固有のヘッダー変更機能を使用して修正するのは簡単です。