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
No.1ベストアンサー
- 回答日時:
脆弱性の詳しい解説は、以下などをじっくり読んで貰うとして
http://www.atmarkit.co.jp/fsecurity/rensai/webho …
画像に限らず、せっかく隠しディレクトリーにおいてあるファイル名をurlのクエリに含めたり、postさせたりするよりは、コード化した方が安全です。
つまり、対象ファイル名すべてを配列に入れておき、画像名の指定は、配列番号で行うといったことです。
参考URL:http://www.atmarkit.co.jp/fsecurity/rensai/webho …
回答ありがとうございます。
なるほど。確かに、おっしゃるとおりですね。
もう一度設計を見直してファイル名を外に出さないように考えてみます。
No.2
- 回答日時:
とりあえずreadfile()はバイナリセーフではないので、
きちんと開いて、読みだして、閉じるほうがよいでしょう。
また、ファイル名でアクセスするのは管理上も面倒ばかり多いので
idをつかってアクセスするような方法に変えた方がいいと思います
(であればだいぶセキュリティ問題も限定できるでしょうし)
回答ありがとうございます。
ファイル名でのアクセスについては No1 の回答者の方も言っている通りあまり良い実装ではないようですね・・改善してみます。
readfile() を使わないということは、fopen、fclose で読み込むと言うことでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- PHP imageフォルダに、画像をリサイズして保存する時のファイル名を変更したい 1 2023/05/30 11:39
- JavaScript clear機能を失わずにファイルアップロード機能を作成したい 3 2023/06/10 16:12
- CGI htmlからパラメータで、cgiに渡したい。 1 2023/02/06 16:15
- PHP PHP MySql 画像を取得 1 2022/06/04 14:05
- PHP PHPで画像の渡しが上手く行きません。 1 2023/02/02 09:39
- PHP 入力した部分を表示させたまま(保持)するにはどうすれば良いでしょうか? 1 2023/01/25 11:14
- HTML・CSS CSSが効かずどのように指定すれば良いか分からないのでアドバイスお願い致します 2 2023/06/07 12:25
- AJAX JavascriptからPHPへのAjax通信でnullが返ってくる 3 2022/08/03 22:00
- PHP 画像が表示出来ません。 1 2023/02/02 16:30
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
重複を防ぐ記述について教えて...
-
mySQLのデータを多次元配列に格...
-
テキストボックスの値を取得したい
-
$_SESSIONに渡した後はそのまま...
-
PHPからデータベースの該当行を...
-
PHPで入力フォームでデータを確...
-
HTMLで前の画面に戻る時、入力...
-
syntax error, unexpected '}' ...
-
laravelを利用してコントロール...
-
form id、nameの番号振りなおし
-
PHPで画像の渡しが上手く行きま...
-
フォームへの前回入力値をクリ...
-
phpで、フォームのラジオボタン...
-
ラジオボタンの値を受け取ってP...
-
ラジオボタンをsessionで使いたい
-
フォームで作った送信ボタンが...
-
同じページでフォームデータを...
-
PHPで、ボタンを押すと同じペー...
-
2つのプルダウンメニュから受け...
-
文字列から抜き出す
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Flaskでサーバー立ち上げに関して
-
重複を防ぐ記述について教えて...
-
VBA で、スペースを含むファイ...
-
phpで変数を使ってcopyできない
-
PHPで入力フォームでデータを確...
-
PHPからHTMLへの変数の受け...
-
POSTの項目に追加
-
PHP MySql 画像を取得
-
MySQL,PHPのリロードによる二重...
-
UPDATEできない
-
ファイル名を変更してアップロ...
-
php、sqlite3にデーター追加で...
-
openCVのトラックバーについて
-
複数条件での検索について教え...
-
PHP5でsimple_xml_load_fileす...
-
PHPのリロード時の処理
-
連想配列を複数条件で比較して...
-
PDOのprepareでLIKEの部分一致...
-
POSTされない
-
アップロードしたファイルの絶...
おすすめ情報