PHP で動的ファイル出力
PHP 猛勉強中です、またお世話になりますm( __ __ )m
ドキュメントルート外に置いたイメージファイルを HP からリンクして表示できるように readfile 関数を使った PHP ファイルを作成しようと思っています。
readfile.php に対して URL クエリーでhttp://hoge/readfile.php?name=hage&ext=jpg のような感じで呼び出したいと思っています。
※ name はファイル名、 ext は拡張子です。
[readfile.php]
<?php
$_name = "";
$_ext = "";
if(isset($_GET["name"]) === true && isset($_GET["ext"]) === true){
// null byte 対策
$_name = delete_nullbyte($_GET["name"]);
$_ext = delete_nullbyte($_GET["ext"]);
// ディレクトリトラバーサル対策
$_name = str_replace(".", "", @htmlspecialchars($_name, ENT_QUOTES, "UTF-8"));
$_ext = str_replace(".", "", @htmlspecialchars($_ext, ENT_QUOTES, "UTF-8"));
}else{
exit();
}
$_file_path = "/home/xxx/img/" . $_name . "." . $_ext;
// ファイル存在確認
if(file_exists($_file_path) === false){ exit(); }
// MimeType 取得
$_ext_type = substr($_file_path, -3);
$_mime_type = "";
if(strcasecmp($_ext_type, "jpg") === 0){
$_mime_type = "image/jpeg";
_out_file($_file_path, $_mime_type);
}else{
exit();
}
/////////////////////////////////////////////////
// ファイル出力
function _out_file($file_path, $mime_type)
{
// ファイル名取得
$_fname = @basename($file_path);
// ファイルストリーム取得
header('Content-Type: ' . $mime_type);
header("Content-Disposition: inline; filename='" . $_fname . "'");
readfile($file_path);
}
/////////////////////////////////////////////////
// null byte 除去メソッド
function delete_nullbyte($str)
{
if(is_array($str) === true){ return ""; }
return str_replace("\0", "", $str);
}
?>
色々作業を進めるうちに「null byte 攻撃」や「ディレクトリトラバーサル攻撃」などの言葉が耳に入ってきてセキュリティ的に不安を感じています。
自分なりに調べて上記のようなコーディングをしましたが、果たして問題が無いのか、それとももっとたくさん考えなくてはならないのか、先輩方の意見が聞きたく質問させていただきました。
よろしくお願いしますm( __ __ )m
お礼
回答ありがとうございます。 これまで2GB以上のファイルを扱ったことがなくこのような問題があったことを知らずデバッグに苦労しました。参考にさせていただきます。