IIS CGI HTTP_PROXY ヘッダー要求がリダイレクトされる可能性がある

適用先
Windows 10 Windows 10, version 1511, all editions Windows Server 2012 R2 Datacenter Windows Server 2012 R2 Standard Windows Server 2012 R2 Essentials Windows Server 2012 R2 Foundation Windows 8.1 Enterprise Windows 8.1 Pro Windows 8.1 Windows RT 8.1 Windows Server 2012 Datacenter Windows Server 2012 Datacenter Windows Server 2012 Standard Windows Server 2012 Standard Windows Server 2012 Essentials Windows Server 2012 Foundation Windows Server 2012 Foundation Windows Server 2008 R2 Service Pack 1 Windows Server 2008 R2 Datacenter Windows Server 2008 R2 Enterprise Windows Server 2008 R2 Standard Windows Server 2008 R2 Web Edition Windows Server 2008 R2 Foundation Windows 7 Service Pack 1 Windows 7 Ultimate Windows 7 Enterprise Windows 7 Professional Windows 7 Home Premium Windows 7 Home Basic Windows 7 Starter Windows Server 2008 Service Pack 2 Windows Server 2008 Datacenter Windows Server 2008 Enterprise Windows Server 2008 Standard Windows Server 2008 Web Edition Windows Server 2008 Foundation Windows Server 2008 for Itanium-Based Systems Windows Vista Service Pack 2 Windows Vista Ultimate Windows Vista Enterprise Windows Vista Business Windows Vista Home Premium Windows Vista Home Basic Windows Vista Starter

現象

IIS Common Gateway Interface (CGI) 機能を使用して、特定のライブラリを使用して要求をリダイレクトする実行可能プログラムをホストしている場合、"PROXY" 要求ヘッダーの存在に基づいて要求が誤って転送される可能性があります。 いくつかの Web アプリケーション プラットフォームでこのライブラリを使用することが知られています。 これらには、PHP、Python、Go などが含まれます。

原因

CGI は、実行可能プロセスとして実行されるアプリケーションを Web サーバーがホストできるようにするインターフェイスです。 Web サーバーが要求を受信すると、サーバーはその 1 つの要求を処理する新しいプロセスを開始します。 要求が完了すると、プロセスは終了します。 プロセスが要求データにアクセスするために、要求ヘッダーは、名前の前に "HTTP_" が付加された環境変数として含まれます。 したがって、"Proxy" という名前のヘッダーを含む要求の CGI プロセスには、要求ヘッダーと同じ値を持つ "HTTP_PROXY" 環境変数があります。

cURL コマンド ラインとライブラリは、さまざまな種類のアプリケーションが Web サーバーを含むさまざまな種類のサーバーに要求を行えるようにするために一般的に使用されます。 このライブラリは、コマンド ライン パラメーターを使用して構成することも、ホスト プロセス環境変数から構成パラメーターを読み取ることもできます。 "HTTP_PROXY" は、cURL で使用される多くの構成パラメーターの 1 つです。 "HTTP_PROXY" は、構成済みプロキシを介して HTTP 要求を送信するために cURL によって使用されます。

注: これは、クライアント要求ヘッダーの表現としての "HTTP_PROXY" とは関係ありません。

cURLが CGI プロセス内でホストされており、そのプロセスに "HTTP_PROXY" という名前の環境変数が含まれている場合、cURL はその値を使用して、環境変数で値が指定されている HTTP プロキシを介して要求されたデータを送信します。 これは、cURL が "HTTP_PROXY" がクライアント要求ヘッダーではなく構成ディレクティブであることを想定しているために発生します。

回避策

この問題を回避するには、IIS を実行しているサーバーで CGI を使用しないでください。 CGI は、ほとんど時代遅れのインターフェイスであり、より新しいパフォーマンス関連のインターフェイスに置き換えられています。 具体的には、PHP、Python、Go は IIS 上の FastCGI を介してホストする必要があります。 FastCGI はクライアント要求ヘッダーに環境変数を使用しないため、この問題はありません。 ただし、PHP の場合、一部のアプリケーションは PHP の getenv() 関数を使用して環境変数を取得する場合があります。 PHP が CGI プロセス内でホストされていない場合でも、getenv() 関数で利用可能なデータ セットに要求ヘッダー値を挿入することで CGI の動作を複製します。 この方法でHTTP_PROXYを取得する PHP アプリケーションを使用する場合は、ヘッダー値をクリアするか、PROXY ヘッダーを含む要求を拒否する次の軽減策が効果的です。

何らかの理由で CGI を使用する必要がある場合は、"Proxy" という名前の要求ヘッダーを含む要求をブロックするか、ヘッダーの値をクリアします。  これは、"Proxy" が標準の要求ヘッダー名ではなく、ブラウザーは通常送信されないためです。

Proxy ヘッダー (推奨されるソリューション) を含む要求をブロックするには、次のコマンド ラインを実行します。

appcmd set config /section:requestfiltering /+requestlimits.headerLimits.[header='proxy',sizelimit='0']
注: 通常、appcmd.exe はパスに存在せず、%systemroot%\system32\inetsrv ディレクトリにあります

ヘッダーの値をクリアするには、次の URL 書き換えルールを使用できます。

<system.webServer>
    <rewrite>
        <rules>
            <rule name="Erase HTTP_PROXY" patternSyntax="Wildcard">
                <match url="*.*" />
                <serverVariables>
                    <set name="HTTP_PROXY" value="" />
                </serverVariables>
                <action type="None" />
            </rule>
        </rules>
    </rewrite>
</system.webServer>

注: URL 書き換えは IIS へのダウンロード可能なアドインであり、既定の IIS インストールには含まれていません。