urllib3: HTTPSプロキシのTLS設定が無視されたり、上書きされたりする可能性がある
## 影響
urllib3は、HTTPSプロキシとターゲットサーバーに対して、TLSの設定を個別に構成することをサポートしています。
`proxy_ssl_context`、`proxy_assert_hostname`、および`proxy_assert_fingerprint`は、プロキシへのTLS接続を設定します。`ssl_context`およびその他のターゲット固有のTLSパラメータは、ターゲットサーバーへの接続を設定します。
urllib3のバージョン1.26.0から2.7.0までの間、これらの設定が常に明確に分離されていたわけではありません。プロキシのモードによっては、urllib3が以下のような動作をする可能性がありました。
1. `proxy_ssl_context`を無視し、HTTPSフォワードプロキシへのTLS接続に、ターゲットサーバーのSSLコンテキストを使用する。
2. HTTPSプロキシの証明書検証ポリシーを、ターゲットサーバーの証明書検証ポリシーで上書きする。
3. ターゲット固有のSNI、ホスト名検証、証明書フィンガープリント検証、またはTLSクライアント認証情報を、HTTPSフォワードプロキシへのTLS接続に適用する。
特に、ターゲットサーバーに対して`cert_reqs="CERT_NONE"`を設定すると、HTTPSプロキシで構成されたSSLコンテキストの`verify_mode`が上書きされる可能性がありました。この変更は、コンテキストオブジェクト内で直接行われ、永続的に保持されるため、後続の接続で同じコンテキストを再利用する場合、プロキシの証明書検証が無効になる可能性がありました。
HTTPSプロキシへの接続を傍受できる攻撃者は、プロキシのTLS設定が証明書検証を無効にしている場合や、攻撃者の証明書をそのまま受け入れる場合に、プロキシになりすますことができる可能性があります。これは、例えば、ターゲットサーバーの信頼またはIDポリシーが誤ってプロキシ接続に適用された場合に発生する可能性があります。
HTTPSフォワードが有効になっている場合、なりすまされたプロキシは、転送されたリクエストとレスポンスを観察または変更することができ、これにより、認証情報、認証トークン、リクエストボディ、レスポンスデータ、およびその他の機密情報が漏洩する可能性があります。
ターゲットサーバーを対象としたTLSクライアント証明書は、プロキシまたはそれを装った攻撃者に提示される可能性があります。これにより、クライアントの身元が明らかになり、対応する秘密鍵の所持の証明となる可能性があります。ただし、秘密鍵自体はTLSハンドシェイク中に送信されません。
CONNECTトンネリングモードでは、HTTPSプロキシを装することは、クライアントとターゲットサーバー間の独立したエンドツーエンドのTLS接続を直接妨げるものではありません。
## 影響を受ける利用状況
urllib3のバージョン1.26.0から2.7.0までのコードは、以下のいずれかの状況で影響を受ける可能性があります。
### 1. ターゲットのSSLコンテキストがHTTPSフォワードプロキシに使用されている場合
HTTPSリクエストが、`use_forwarding_for_https=True`で設定されたHTTPSプロキシを介して転送され、プロキシに対して`proxy_ssl_context`が設定されている場合。
urllib3が`proxy_ssl_context`を無視し、プロキシのTLSハンドシェイクにターゲットサーバーの`ssl_context`を使用する可能性があります。その結果、プロキシの検証に、プロキシに明示的に設定されたポリシーではなく、ターゲットサーバーの信頼および証明書ポリシーが使用される可能性があります。
### 2. ターゲットの検証ポリシーがプロキシのポリシーを上書きする場合
HTTPSプロキシが`proxy_ssl_context`で設定されている一方で、ターゲットサーバーが異なる証明書検証ポリシーを使用している場合。
urllib3が、ターゲットサーバーの`cert_reqs`の値をプロキシのSSLコンテキストに適用する可能性があります。例えば、ターゲットサーバーで`cert_reqs="CERT_NONE"`が設定されている場合、HTTPSプロキシの証明書検証が無効になる可能性があります。これは、`proxy_ssl_context`が検証を要求するように設定されている場合でも発生する可能性があります。
この問題は、フォワードおよびCONNECTトンネリングの両方の構成において、HTTPSプロキシへのTLS接続に影響を与える可能性があります。
### 3. 変更されたプロキシSSLコンテキストが再利用される場合
同じSSLコンテキストが、複数の接続で`proxy_ssl_context`として再利用され、あるターゲットサーバーに対して証明書検証が無効になっている場合。
urllib3は、プロキシのSSLコンテキストの`verify_mode`を直接変更する可能性があります。 そのため、同じコンテキストを再利用する後続の接続では、証明書の検証なしでHTTPSプロキシに接続される可能性があります。
### 4. ターゲット固有のTLS識別情報または認証情報がプロキシに適用されます。
HTTPSリクエストは、`use_forwarding_for_https=True`とともにHTTPSプロキシを介して転送され、ターゲット固有のSNI、ホスト名アサーション、証明書フィンガープリントアサーション、またはTLSクライアント認証情報が構成されます。
urllib3は、これらのターゲット固有の設定をプロキシのTLSハンドシェイクに適用する可能性があります。 これにより、urllib3が以下を行う可能性があります。
- ターゲットサーバーを対象としたSNIをプロキシに送信する。
- ターゲットサーバーを対象としたホスト名または証明書フィンガープリントを使用してプロキシを検証する。
- ターゲットサーバーを対象としたTLSクライアント証明書をプロキシに提示する。
通常のHTTPプロキシを介して接続するコードは、プロキシへのTLS接続を確立せず、この問題の影響を受けません。
## 対策
urllib3 2.8.0以降にアップグレードしてください。
urllib3 2.8.0では、明示的に構成された`proxy_ssl_context`と、プロキシ固有の証明書アサーションが、HTTPSプロキシ接続に個別に適用されます。 ターゲット固有のSNI、証明書アサーション、およびTLSクライアント証明書パラメータは、HTTPSプロキシハンドシェイクには適用されなくなりました。
後方互換性のために、`use_forwarding_for_https=True`を使用し、`proxy_ssl_context`が提供されていない場合、urllib3 2.8.0は引き続きプロキシへのTLS接続に`ssl_context`を使用します。 この構成では`FutureWarning`が発行されます。 urllib3 3.0では、`use_forwarding_for_https=True`とともに`ssl_context`をHTTPSプロキシに渡すとエラーが発生します。 アプリケーションは、HTTPSフォワードプロキシのTLSを設定するために`proxy_ssl_context`を使用する必要があります。
これらの修正は、コミットb6447295fff7b38fdffc67e0df9712d60cef3cc3および07408cec79d1856d81bb42c74a904a24fdb9e465で実装されました。
影響を受けるパッケージ:
- pip (Python) urllib3: 影響を受けるバージョンは1.26.0以上、2.8.0未満、修正されたバージョンは2.8.0。