Dulwich: `filter-branch`のインデックスフィルタにおけるシンボリックリンクによるディレクトリトラバーサル脆弱性

## 概要

Dulwichの`filter_branch.py`にある`CommitFilter._apply_index_filter()`には、シンボリックリンクによるディレクトリトラバーサル脆弱性があります。コミット履歴を処理する際、マテリアライズされたツリーエントリ(シンボリックリンクを含む)が、コミット間でワーキングディレクトリに保持されます。これにより、親コミットからのシンボリックリンクが、子コミットからのファイル書き込みを、任意のファイルシステム上の場所にリダイレクトする可能性があります。

## 根本原因

`dulwich/filter_branch.py:212`の`_apply_index_filter()`は、`build_index_from_tree(".", tmp_index_path, ...)`を呼び出します。この関数は、すべてのツリーエントリを現在のワーキングディレクトリにマテリアライズします。`finally`ブロック(229-230行目)では、一時的なインデックスファイル(`os.unlink(tmp_index_path)`)のみを削除しますが、ワーキングディレクトリに書き込まれたファイルシステム上のファイルは削除しません。`process_commit()`が、まず親を再帰的に処理する(260行目)ため、親コミットからマテリアライズされたファイルが保持され、子コミットの処理に影響を与えます。

Dulwich 1.2.7では、`build_file_from_blob()`にシンボリックリンクの保護がなく、`validate_path_element`はファイル名のパターンのみを検証し、ファイルシステムの状態は検証しません。

## 影響

攻撃者は、悪意のあるリポジトリを作成し、`filter_branch`をインデックスフィルタ付きで実行することで、シンボリックリンクのトラバーサルを利用して、任意のファイルシステム上の場所に攻撃者が制御するコンテンツを書き込むことができます。この攻撃が成功すると、`.git/hooks/`ディレクトリに書き込まれる可能性があり、リモートコード実行(RCE)につながる可能性があります。

## 攻撃シナリオ

1. 攻撃者は、コミット履歴が線形化されたリポジトリを作成します。このリポジトリには、以下のエントリが含まれます。
- 親コミット: ツリーエントリ `evil` (モード 120000、シンボリックリンク → `/target_dir`)
- 子コミット: ツリーエントリ `evil/payload` (モード 100644、攻撃者によるコンテンツ)
2. 攻撃者は、リポジトリをクローンし、インデックスフィルタを使用して `filter_branch` を実行します。
3. `process_commit()` は、まず親コミットを処理します → `evil` を、現在の作業ディレクトリ (CWD) 内の `/target_dir` へのシンボリックリンクとして実現します。
4. CWD は、コミット間の処理でクリアされません。
5. 子コミットの処理: `os.path.exists("./evil")` → True (シンボリックリンクが存在します)。 `build_file_from_blob(blob, mode, "./evil/payload")` → `open("./evil/payload", "wb")` は、中間的なシンボリックリンクを辿り、`/target_dir/payload` に書き込みます。

## 提案される修正

`_apply_index_filter()` 内で、コミットの反復処理の間で CWD をクリアするか、ファイル書き込み前に、中間的なパスの構成要素がシンボリックリンクではないことを検証してください。

報告者: **zx (Jace)**

影響を受けるパッケージ:
- pip (Python) dulwich: 影響あり。バージョン >= 0.23.1、<= 1.2.7 が対象。1.2.8 で修正済み。