フォームの検証は、あらゆる Web アプリケーションの重要な部分であるため、リストに記載されていることを確認することをお勧めします。ここでは、Web アプリケーションの最も危険な 2 つの要素、ファイルのアップロードとデータベースのやり取りを組み合わせているため、慎重に処理する必要があります。それがあなたが求めている理由だと思います!
アプローチに関する私の提案は、まず、ユーザーが提出したファイル名を使用しないことです。これにより、必要のないリスク全体が開かれます。これがアプリの必須機能でない限り、PHP で新しいランダム ファイル名を生成し、move_uploaded_file を使用して、PHP によって割り当てられた tmp_name から新しいランダム ファイル名にコピーします。
この移動を実行したら、ファイルの場所でデータベースを更新できます。
したがって、私のアプローチは次のようになります。
- ホワイトリスト (提案として [az][AZ][0-9]) に基づいて、ユーザーが入力した入力を厳密に検証します。
- ユーザーが提供したデータを画面にエコーバックしないようにします。そうする場合は、出力を HTML エンティティにエンコードします。
- データベースまたはファイル名への入力にユーザー提供のデータを使用することは避け、制御できる新しいファイル名を生成します。
- アップロード自体を処理し、いくつかの検証チェックを実行した後、生成されたファイル名に従って画像を新しい場所に移動します。
- データベースを新しいファイル名で更新します。
あなたがコードを求めていなかったことは知っていますが、ここに私が持っている作業ファイルのアップロードからの小さなスニペットをいくつか示します。データベースの部分は実行しませんが、追加するのは簡単です。
function generate_filename() {
// could be improved upon really
$random_string = random_string(8);
$filename = $random_string . time() . ".jpg";
return $filename;
}
if ($_FILES["file_upload"]["size"] != 0) {
$file_name = generate_filename();
$file_path = "/" . $upload_directory . "/" . $file_name;
$target_file_name = SITE_ROOT . $file_path; // SITE_ROOT is a constant for the file system location. This could be /var/www/images for example.
if ($_FILES["file_upload"]["type"] == "image/jpeg") {
if (getimagesize($_FILES["file_upload"]["tmp_name"])) {
if (move_uploaded_file($_FILES["file_upload"]["tmp_name"],$target_file_name)) {
exit_status("File uploaded successfully to $file_path");
} else {
exit_status("Eek, something went wrong with your image upload");
}
} else {
exit_status("Not a valid image");
}
} else {
exit_status("Invalid file type. We only support JPEG");
}
} else {
exit_status("You didn’t specify a file to upload. Try again");
}