A. 日本語がファイル名に含まれていないか?
B. ファイル名にA-Za-z_-. 以外の文字が含まれていないか?
C. POST時にエラーが発生していないか?
D. ファイル名が空でないか?
E. 不正なパスを表す文字列がファイル名に含まれていないか?( / や ../ など )
F. ファイルサイズが0バイトより大きく指定値以内か?
G. 本当にアップロードされたファイルなのか?(is_uploaded_file()で確認します)
H. 既存ファイルが存在していないか?(削除して上書きする、またはエラーとするか?)
上記は、https://teratail.com/questions/30411 より転記。
その他、
I. ファイル名をハッシュ化して移動・保存。(move_uploaded_fileを使うタイミングで)
J. png,jpg,pdfなど拡張子を制限する。
K. SWFファイルの制限。
L. 保存フォルダを公開ディレクトリから外す(アクセスし、phpなどが実行されたくないためであり、読み込みはreadfileを使う)
M.
<?php $maxsize = $_POST["MAX_FILE_SIZE"]; $extension = array("image/jpeg", "image/png", "application/pdf"); $ds = DIRECTORY_SEPARATOR; $storeFolder = "temp_dir"; //同じディレクトリ内にある一時保存用ディレクトリ $DirPath = dirname( __FILE__ ).$ds.$storeFolder.$ds; $CookieData = $_COOKIE["CookieData"]; //事前にユーザ毎に付与しているランダムな文字列 //[アップロード]ボタンの押下確認 if (isset($_POST["upload"])) { foreach($_FILES["upfile"]["tmp_name"] as $no => $tmp_name){ //エラーはないか? if(!empty($_FILES["upfile"]["name"][$no]) && empty( $_FILES["upfile"]["error"][$no])){ //サイズは超えていないか? if(($_FILES["upfile"]["size"][$no] > 0) && ($_FILES["upfile"]["size"][$no] < $maxsize)){ //アップロードされたファイルか? if(is_uploaded_file($_FILES["upfile"]["tmp_name"][$no])){ //拡張子を判定する $type = mime_content_type($_FILES["upfile"]["tmp_name"][$no]); if(in_array($type, $extension)){ //一時保管されているファイル名 $tempFile = $_FILES["upfile"]["tmp_name"][$no]; //アップロードされたファイル名 $filename = $_FILES["upfile"]["name"][$no]; $file = explode(".", $filename); $ext = array_pop($file); //md5でハッシュ化。別のユーザーと同名のファイル名であったとしても被らないよう、 //事前にユーザ別にランダムな文字列をcookieに持たせており、その値をファイル名へ。 //また、ファイル数に応じて、番号も付与。 //ファイル名を取得する際、basename()を用いることでファイルシステムトラバーサル攻撃は防げる //とのことだが、ハッシュ化すればその対策は必要ないのだろうか?? $new_filename = $CookieData."-".$no.md5($filename).".".$ext; //設定するファイル $targetFile = $DirPath.$new_filename; //一時保管用にハッシュ化したファイルをセット if(move_uploaded_file($tempFile,$targetFile)){ //*** 画像ファイルだったらサイズ変更 *** if($type != "application/pdf"){ $upfile = $storeFolder."/".$new_filename; list($width, $height, $mime_type) = getimagesize($upfile); if($width > 1000){ //1000pxを超えるとき $hiritsu = 1000 / $width; $width_edit = floor($width * $hiritsu); $height_edit = floor($height * $hiritsu); switch($mime_type){ //jpegの場合 case IMAGETYPE_JPEG: $src = imagecreatefromjpeg($upfile); break; //pngの場合 case IMAGETYPE_PNG: //拡張子の設定 $src = imagecreatefrompng($upfile); break; } $dst = imagecreatetruecolor($width_edit, $height_edit); imagecopyresampled($dst, $src, 0, 0, 0, 0, $width_edit, $height_edit, $width, $height); imagejpeg($dst, $upfile); } }//********************** $error .= $no."成功です。<br />"; } else{ $error .= $no."失敗です。<br />"; } } else{ $error .= $no."この拡張子は利用できません。<br />"; } } else{ $error .= $no."ファイルがアップロードされていません。<br />"; } } else{ $error .= $no."ファイルサイズが指定サイズを超えています。<br />"; } } else{ $error .= $no."ファイルアップロードエラーです。<br />"; } } } ?> <html lang="ja"> <head> <meta charset="utf-8"> <script> <!-- //アップロードを許可する拡張子 var allow_exts = new Array('jpg', 'jpeg', 'png', 'pdf'); //フォーム内容の確認をする関数 function checkForm() { var files = document.getElementsByName('upfile[]')[0].files; //ファイルが選択されているか確認 if (files.length == 0) { alert('ファイルを選択してください'); return false; } //指定されたファイルの数だけ拡張子をチェックする for (var i = 0; i < files.length; i++) { if (!checkExt(files[i].name)) { alert(files[i].name+'はアップロードできません'); return false; } } //チェックを通ったらtrueを返す return true; } //アップロード予定のファイル名の拡張子が許可されているか確認する関数 function checkExt(filename) { //比較のため小文字にする var ext = getExt(filename).toLowerCase(); //許可する拡張子の一覧(allow_exts)から対象の拡張子があるか確認する if (allow_exts.indexOf(ext) === -1) return false; return true; } //ファイル名から拡張子を取得する関数 function getExt(filename) { var pos = filename.lastIndexOf('.'); if (pos === -1) return ''; return filename.slice(pos + 1); } --> </script> </head> <body> <h1>アップロード処理</h1> <?php echo $error; ?> <form action="./" enctype="multipart/form-data" method="post" onsubmit="return checkForm();"> <input type="hidden" name="MAX_FILE_SIZE" value="5097152"> <input type="file" name="upfile[]" accept=".jpg,.png,image/jpeg,image/png,application/pdf" /><br /> <input type="file" name="upfile[]" accept=".jpg,.png,image/jpeg,image/png,application/pdf" /><br /> <input type="file" name="upfile[]" accept=".jpg,.png,image/jpeg,image/png,application/pdf" /><br /> <input type="submit" name="upload" value="アップロード"> </form> </body> </html>
コメント