ひとことで言うと
path traversalは「ディレクトリトラバーサル」とも呼ばれるWebセキュリティの古典的な脆弱性です。攻撃者が`../`(1つ上のディレクトリへ移動)を組み合わせたパスをパラメーターとして送ることで、サーバー上の任意のファイルを読み取ったり削除したりできる状態になります。ZIPファイルのエントリー名に`../secret.conf`のようなパスを埋め込んだ「ZIPスリップ」はpath traversalのZIP特有の亜種です。
ZIPスリップ攻撃は2018年にSnykが公開した脆弱性レポートで広く知られるようになりました。多くの言語の標準ZIPライブラリが解凍時にエントリー名をそのままファイルパスに使っていたため、解凍先ディレクトリの外にファイルが書き込まれる問題が多数のプロジェクトで見つかりました。現在は主要ライブラリが修正されていますが、古いバージョンを使っているサービスやカスタム実装には今も注意が必要です。
- 相手がログインなしで開ける状態か確認する
- PCとスマホで最低1回ずつ表示を確認する
- 内部情報・個人情報・不要な外部送信が残っていないか見る
- レビュー期限と修正時の差し替え方を決めておく
HTML共有で関係する場面
ZIPをアップロードしてHTMLサイトを公開するサービスでは、ZIPを解凍して指定ディレクトリにファイルを配置します。この際エントリー名を正規化せずにそのままファイルパスに使うと、`../../../var/www/html/config.php`などのパスに書き込みが起きる可能性があります。信頼できるサービスは`path.resolve()`や`os.path.abspath()`を使ってエントリーパスを正規化し、解凍先ディレクトリの外に出ないことを確認してから書き込みを行います。
利用者側でも、AIツールが生成したZIPをアップロードする前に中身を確認することで予防できます。`unzip -l archive.zip`を実行してファイルリストを表示し、`..`が含まれるパスがないか確認してください。正常なHTMLサイトのZIPであれば`index.html`や`assets/style.css`のような相対パスのみが含まれ、上位ディレクトリへの参照は一切ないはずです。
よくある誤解
「ZIPを展開するだけのサービスだからセキュリティリスクはない」という誤解が危険です。展開処理そのものがリスクであり、特に解凍先をWebサーバーのルートディレクトリと同じ場所に設定している場合は、攻撃成功時にサーバー設定ファイルが上書きされたり任意コードが実行されたりする深刻な結果につながります。
「HTTPS通信だからpath traversalは防げる」という認識も誤りです。HTTPSは通信路の暗号化を提供しますが、サーバー側のファイルシステム操作には関係しません。悪細工されたZIPはHTTPSを通じて正常に送信されます。対策はサーバー側のパス正規化処理であり、通信の暗号化とは独立した問題です。
安全に使うための注意点
ZIPを解凍するサービスを開発する際は、各エントリーのパスを`path.join(destDir, entry.fileName)`で計算したあと、`path.resolve()`して`startsWith(destDir)`で始まることを必ず確認してください。この2行の検証を省略すると、どれだけ他の部分を堅牢に作ってもZIPスリップの穴が残ります。Pythonでは`zipfile.ZipFile`の`extract`メソッド使用時に同様のチェックが必要です。
利用するHTML共有サービスを選ぶ際は、脆弱性への対応実績や利用規約のセキュリティ項目を確認する習慣をつけてください。GitHubのセキュリティアドバイザリで当該サービスが利用するZIPライブラリの CVEを検索し、修正済みバージョンを使っているか確認するのも有効な方法です。
よくある質問
ZIPスリップ攻撃は受け取ったZIPをそのまま配信する場合にも影響しますか?
ファイルを解凍せず元のZIPをそのまま配信するだけなら、パストラバーサルのリスクはありません。リスクが発生するのはサーバー側でZIPを展開してファイルシステムに書き込む処理がある場合です。
ZIPスリップに対して現在のNode.jsの主要なZIPライブラリは安全ですか?
yauzlやadm-zipは比較的古い問題への対処がされていますが、パス正規化を開発者側でも行うことを推奨します。ライブラリのバージョンと最新のCVEを定期的に確認し、パッチが出たら迅速に適用してください。
path traversalはURL経由でも起きますか?
はい。`/download?file=../../etc/passwd`のようなURLパラメーターを受け取るAPIでも同様のリスクがあります。ユーザー入力を直接ファイルパスに組み込まず、許可されたファイル名のホワイトリストを使うか、IDで参照してサーバー側でパスに変換する設計が安全です。