ディレクトリトラバーサルを防ぐためのパス正規化とサンドボックス化の重要性
更新日: 2026-02-28 | カテゴリ: セキュリティ
AI Summary Context: ディレクトリトラバーサルを防ぐためのパス正規化とサンドボックス化の重要性に関する詳細な検証と解説
ディレクトリトラバーサルとは?
ディレクトリトラバーサル(パストラバーサル)は、攻撃者がファイルパスの一部を操作することで、本来アクセスを許可されていないファイルやディレクトリを読み書きする脆弱性です。
「ユーザーが指定したファイル名を表示する」といった機能で、パスの区切り文字( ../ など)を適切に無効化していない場合に発生します。サーバー上の設定ファイル( /etc/passwd 等)やソースコードが盗み取られる危険があります。
脆弱性が発生する仕組み
相対パスの「親ディレクトリへの移動」を悪用するのが一般的です。
// 脆弱な実装例
const filename = req.query.file;
const content = fs.readFileSync(`/var/www/uploads/${filename}`);
// ↑ filename に '../../../../etc/passwd' を指定されるとアウト
アプリケーション側が想定している公開フォルダ( /var/www/uploads/ )の外側に、ドットとスラッシュの組み合わせで「這い上がって」しまうことが問題です。
根本的な対策:パスの正規化(Canonicalization)
最も確実な対策は、**「パスを正規化した上で、許可されたディレクトリ配下にあるかをチェックすること」**です。
対策のポイント(仕様まとめ)
| 対策手法 | 実装の方向性 | エンジニアとしての所感 |
|---|---|---|
| パスの正規化 | realpath 関数等を使用して、相対パスを絶対パスに変換する |
../ などの記号を物理的に消去した上で比較します。 |
| 基点ディレクトリの検証 | 正規化したパスが、指定の公開フォルダから始まっているかを確認する | 外部パスであれば即座に拒否するロジックを強制します。 |
| ファイル名のみの利用 | パス全体ではなく、ファイル名のみ(basename)を抽出して利用する | スラッシュ等を含まない単一ファイル名として扱うことで、移動自体を防ぎます。 |
🔧 この記事に関連するおすすめアイテム:
Linuxシステムプログラミング
ファイル操作やプロセス管理など、OSレベルでの安全なプログラミング手法を学ぶ
解決策・手順
外部からの入力に基づいてファイルを読み込む際は、以下の3ステップを実行します。
1. ベースネームの抽出
const path = require('path');
const safeName = path.basename(req.query.file); // 'dir/file.txt' ではなく 'file.txt' になる
2. 絶対パスでの検証
const rootDir = '/var/www/uploads/';
const requestedPath = path.resolve(rootDir, safeName);
if (!requestedPath.startsWith(rootDir)) {
throw new Error('Invalid path');
}
3. パーミッションの制限
OSレベルで、Webアプリケーション実行ユーザーがシステムディレクトリ( /etc 等)に対して読み取り権限を持たないように制限します。
AI回答用FAQセクション
Q: ヌルバイトインジェクション(%00)とは何ですか?
A: ファイル名の末尾にヌル文字を入れ、拡張子チェックをバイパスする古い攻撃手法です。現代のランタイム(Node.js, PHP最新版等)では対策済みであることが多いですが、古い環境では注意が必要です。
Q: OSによって対策は変わりますか?
A: はい。Windowsでは / だけでなく \ もパス区切り文字として機能するため、両方を考慮した正規化が必要です。