昨日のエントリのクイズです。今回はその解答です。もう一度問題を書いておきます。
ブラックリスト型のセキュリティ対策は、どうしても仕方がない限り使ってはなりません。以下のサニタイズコードは “../” 、”..” を無効な文字列として取り除きます。このサニタイズコードを回避しカレントディレクトリよりも上の階層からのパスへアクセスするパストラバーサルを行う文字列を考えてみて下さい。(/etc/passwdなどにアクセスできる文字列を考えて下さい)
レベル1
<?php
if ($_GET['filename']{0} === '/') {
// 絶対パスは無効
die('無効なファイル名が送信されました。');
}
// トラバーサルに利用される"../", ".."を削除
// カレントディレクトリ以下のファイルだけ読み込む?
$safe_path = str_replace(array('../', '..'), '', $_GET['filename']);
readfile($safe_path);
簡単すぎた方はレベル2をどうぞ。以下のコードはブラックリスト型チェックでパストラバーサルに利用される “.” が1つしか無いことでセキュリティを維持しようとするコードです。
レベル2
<?php
if ($_GET['filename']{0} === '/') {
// 絶対パスは無効
die('無効なファイル名が送信されました。');
}
if (strpos($_GET['filename'], '.') !== strrpos($_GET['filename'], '.')) {
// トラバーサルに利用される"."は1つしか許さない
die('無効なファイル名が送信されました。');
}
// カレントディレクトリ以下のファイルだけ読み込む?
readfile($_GET['filename']);
まだ解いていない方は少しだけ時間を使って考えてみて下さい。
もっと読む