To answer your questions:
- You do not need to use all of these methods, and which ones you use based on personal opinion. There is more than one completely safe way to do this, so don't be surprised if you get several different answers.
- See the examples below for additional checks that you may not have considered.
- Yes, order definitely matters.
Depending on your application, the logic of any secure boot should go something like this:
User logged in? (Not necessary)
// make sure user is logged in if (!$user->loggedIn()) { // redirect }
Does the user have permission? (not necessary)
// make sure user has permission if (!$user->isAllowed()) { // redirect }
Was the form submitted?
// make sure form was submitted if ($_SERVER['REQUEST_METHOD'] == 'POST') {
Is the form type entered correctly?
// validate CSRF token // ... // make sure there were no form errors if ($_FILES['file']['error'] == UPLOAD_ERR_OK) { // make sure the file size is good if ($_FILES['file']['size'] <= MAX_FILE_UPLOAD) { // make sure we have a valid image type $type = exif_imagetype($_FILES['file']['tmp_name']); if ($type !== false) { // make sure we check the type against a whitelist if (in_array(ltrim(image_type_to_extension($type), '.'), array('jpeg', 'jpg', 'png'))) {
Even after verification, never trust user input
// give the file a unique name $hash = hash_file('sha1', $_FILES['file']['tmp_name']); $ext = image_type_to_extension($type); $fname = $hash . $ext;
Save the file (or perhaps re-create it using the library to extract metadata), but NEVER in a public directory
$upload_path = '/path/to/private/folder'; move_uploaded_file($_FILES['file']['tmp_name'], "$upload_path/$fname");
The above steps are absolutely safe and more than reasonable, of course, there is always a risk that some other part of your application or server may be vulnerable.