「ちょっとそこまで」が命取り?Webの「泥棒」を阻むパス・トラバーサルの基礎知識
こんにちは!セキュリティの世界へようこそ。今日は、Webサイトの裏側でこっそり行われる「パス・トラバーサル(ディレクトリ・トラバーサル)」という攻撃についてお話しします。
名前だけ聞くと難しそうですが、仕組みを理解すれば怖くありません。まるで「家の防犯」と同じように、一歩ずつ対策を学んでいきましょう!
—
1. パス・トラバーサルって、結局なに?
例えるなら、「合鍵を渡したつもりが、勝手に家中のドアを開けられてしまった」ような状態です。
Webサイトには、画像ファイルやPDFをダウンロードさせる機能がありますよね。プログラムは「このフォルダの中にある画像を持ってきてね」という命令を受け取ります。
このとき、攻撃者は「隣の部屋(本来見せてはいけない設定ファイル)」を覗こうと、意地悪な道順を指定してくるのです。
泥棒の通り道:../(ドット・ドット・スラッシュ)
パソコンのファイル操作で「一つ上の階層に戻る」ときに使う ../ という記号をご存知でしょうか?
本来なら「画像フォルダ」の中にいるはずのプログラムに、この記号を連続で送ることで、「画像フォルダ」から脱出して、サーバーの心臓部であるシステム設定ファイルへ無理やり移動しようとする。これがパス・トラバーサルの正体です。
—
2. なぜそんなことが起きるの?(脆弱なコードの例)
まずは、やってはいけない「危ないコード」を見てみましょう。PHPで書かれた、ファイルを読み込む処理の例です。
<?php
// ユーザーから送られてきたファイル名を受け取る(ここが危険!)
$filename = $_GET['file'];
// 受け取った名前をそのままパスとして結合している
$filepath = "/var/www/html/uploads/" . $filename;
// 中身を読み込んで表示する
echo file_get_contents($filepath);
?>
このコードの何が問題かというと、「ユーザーの言うことを100%信用している」点です。
もし攻撃者が ?file=../../../../etc/passwd というリクエストを送ってきたら、サーバーは /var/www/html/uploads/../../../../etc/passwd というパスを解釈し、Linuxシステムの重要なパスワードファイルを読み取って画面に表示してしまうのです。
—
3. 「一歩ずつ」対策を学ぼう!
では、どうすれば泥棒を防げるのでしょうか? 守りの鉄則は「信用しないこと」です。
対策1:ファイル名を直接使わない(ホワイトリスト方式)
ユーザーからの入力はすべて「疑わしいもの」として扱い、あらかじめ許可したファイル名リストと照らし合わせるのが一番安全です。
<?php
// 許可されたファイルリスト
$allowed_files = ['image1.jpg', 'doc.pdf'];
$filename = $_GET['file'];
// リストに含まれているかチェック!
if (in_array($filename, $allowed_files)) {
echo file_get_contents("/var/www/html/uploads/" . $filename);
} else {
echo "そんなファイルはありません!";
}
?>
対策2:パスを正規化(きれいにする)
どうしても名前で指定したい場合でも、basename() 関数を使ってディレクトリ指定の記号(/や..)を削除してしまうのが有効です。
$filename = basename($_GET['file']); // "dir/../file.txt" なら "file.txt" になる
$filepath = "/var/www/html/uploads/" . $filename;
—
4. Webサーバーの設定でも防御しよう
アプリケーションだけでなく、Webサーバー(ApacheやNginxなど)の設定で、そもそも「Webの公開フォルダから外に出させない」という物理的な壁を作ることも大切です。
- ドキュメントルートの制限: Webサーバーがアクセスできる範囲を必要最小限のディレクトリに絞りましょう。
- 権限の管理: Webサーバーを動かしているユーザー(例:
www-data)に、システム設定ファイル(/etc/shadowなど)を読み取る権限を与えないようにしてください。「鍵のかかっていない部屋」を作らないことが、最大の防犯です。
—
最後に:セキュリティは「泥棒とのいたちごっこ」
パス・トラバーサルのような攻撃は、Webサイトを公開している限り、世界中のどこからでも狙われる可能性があります。しかし、今回お伝えした「入力値を信じない」「許可した範囲から出さない」という基本さえ守れば、突破されるリスクを劇的に減らすことができます。
皆さんの書くコードが、今日のこの知識で少しでも強固なものになることを願っています。セキュリティは、知識という「頑丈な鍵」をかけることから始まります。また一緒に学んでいきましょうね!
コメント