作成・保守: Sergio Rodriguez (SSH-PuR66)。 実験ハーネスと分析は私によるものです。公開された脆弱性、urllib3 のコード、および上流の修正は元の帰属を保持しています。
著者の研究方法 · リダイレクトハーネス · チャンクフレーミング研究
リダイレクトは宛先を変更する一方で、3つの機密ヘッダーが付いたままになります。フレーミングパーサーは、次のリリースでは拒否される入力を受け入れます。Afterimage は、公開されたプロトコル修正を、小さく検査可能なビフォー/アフター実験へと変えます。
私は、固定された未改変の urllib3 リリースを対象にハーネスとコントロールケースを構築しました。各結果には、パッケージハッシュ、キャプチャした挙動、フィクスチャ境界、上流の帰属が記録されています。
| 研究 | 比較リリース | 記録コーパス | 検査 |
|---|---|---|---|
| リダイレクトヘッダー境界 · CVE-2026-44431 | urllib3 2.6.3 / 2.7.0 | 影響を受ける挙動と無害なコントロールを含む12ケース | 結果 · ハーネス |
| チャンクフレーミング · CVE-2026-97689 | urllib3 2.7.0 / 2.8.0 | 32件の境界付きオフラインケース | 手法と結果 |
研究種別: 公開された問題の独立再現。測定された境界: ライブラリの引数処理とインメモリのフレーミング挙動。アプリケーション上の悪用可能性およびリソース枯渇は、これらのフィクスチャ結果の範囲外です。
CVE-2026-44431 · urllib3 2.6.3 → 2.7.0 · 2026年9月27日再現
あるリクエストが3つの機密ヘッダーを1つのオリジンへ運びます。リダイレクトが宛先を変更します。次のリクエストは依然としてそれらを運ぶのでしょうか?
この独立したリグレッションは、2つの正確な urllib3 リリースから実際のリダイレクト実装を実行します。バージョン 2.6.3 は、影響を受ける低レベル API を通じて3つのヘッダーすべてを保持します。バージョン 2.7.0 はそれらを削除します。無害なヘッダーは存続し、通常のリクエストも引き続き機能します。
| フィクスチャ | urllib3 2.6.3 | urllib3 2.7.0 |
|---|---|---|
| 低レベルクロスオリジンリダイレクト | 機密ヘッダー3件を保持 | 0件保持 |
| 小文字名での同一ケース | 3件保持 | 0件保持 |
| 高レベル API コントロール | 0件保持 | 0件保持 |
| 直接の 200 レスポンス | 意図どおり3件保持 | 意図どおり3件保持 |
| リダイレクトを明示的に無効化 | 1回の呼び出し。302 を返す | 1回の呼び出し。302 を返す |
| カスタム削除セットに無害なマーカーを追加 | 4件すべて保持 | 4件すべて削除 |
12/12 のシナリオ期待値が合格。 各シナリオはさらに、レスポンスステータス、トランスポート呼び出し回数、初期ヘッダーセット、無害ヘッダーの結果、および呼び出し元のヘッダーが変更されていないことを検証します。脆弱な結果は期待されるベースライン結果であり、合格するセキュリティチェックではありません。
機械可読な結果には、キャプチャした引数、正確な wheel ハッシュ、ランタイム、テストソースのハッシュ、帰属、再現時刻が含まれます。
2026年5月7日に公開された上流のアドバイザリは、urllib3 のプロキシ経由の低レベルリダイレクトパスにおける情報露出の問題を特定しています。影響を受けるバージョンとして >=1.23, <2.7.0 を挙げています。ProxyManager.connection_from_url(...).urlopen(..., assert_same_host=False) を呼び出すと、設定された機密ヘッダーが別のオリジンへのリダイレクトされたリクエストに持ち込まれる可能性がありました。高レベルのマネージャ API はすでにそれらを削除していました。
上流の修正は、再帰的な低レベルリクエストの前に Retry.remove_headers_on_redirect を適用します。私たちの小文字ヘッダーのケースは、上流のリグレッションによるヘッダー名の大文字小文字への配慮に倣っています。カスタム削除のケースは、ルールが3つのデフォルト名だけでなく、設定されたセットを尊重することを確認します。
アドバイザリでは、christos-cantina-security を報告者、illia-v をコーディネーター、sethmlarson を修正レビュアーとしてクレジットしています。ここでの Sergio Rodriguez の貢献は、独立したオフラインハーネスとビフォー・アフター分析です。これは彼らが公開した CVE の再現です。
Python 3.10 以降を使用してください。pip install や仮想環境は不要です。各バージョンは、新しく分離されたサブプロセス内で、その純粋な Python wheel から直接インポートされます。
ポートフォリオリポジトリのルートから:
python -B ./labs/cve-replay/run_replay.py --fetch
python -B ./labs/cve-replay/run_replay.py
最初のコマンドは、2つの正確なwheelをラボの無視対象ディレクトリ.cache/wheels/にダウンロードし、マニフェストと照合してSHA-256ハッシュを検証します。2番目のコマンドは、ダウンロードを行わずにそのキャッシュを使用します。スタンドアロンのソースチェックアウトでは、python -B run_replay.py --fetchを実行し、その後--fetchを付けずに同じコマンドを実行します。--cacheは別のローカルキャッシュディレクトリを受け付けます。
HTTPConnectionPool._make_requestは、2つのレスポンスを返すトランスポートに置き換えられます。まず固定されたlocationを持つ302、次に200です。フィクスチャは、その境界に到達する引数をキャプチャします。urllib3のパース、リトライポリシー、ヘッダーフィルタリング、および再帰的なリダイレクト処理は、選択されたwheelから変更なしで実行されます。
すべての宛先は固定された予約済みの.invalid名です。すべてのヘッダー値はDUMMYで始まります。ソケット構築とDNS関数は即座に例外を発生させます。ライブラリのインポート時のIPv6機能プローブは拒否され、別途記録されます。リプレイシナリオはネットワーク操作を一切試行しません。待ち受けサーバーやライブターゲットは存在しません。
これはリダイレクト引数の処理を検証します。エンドツーエンドのプロキシトラフィックを測定するものではありません。バージョン2.7.0は、この特定のCVEに対する最初の修正です。この歴史的な比較は、新しいサポート対象リリースよりもそれを選択することを推奨するものではありません。
フィクスチャスクリプトと分析は、オリジナルのポートフォリオ作品です。urllib3は、そのMITライセンスの下で配布されているアップストリームプロジェクトです。そのコードとリリースwheelは、ポートフォリオのソースアーカイブには再配布されていません。これらはPyPIから別途ダウンロードされ、実験のために変更なしでインポートされます。