Безопасный способ загрузки изображений php и GIF

Aug 20 2020

Я создаю социальную сеть и хочу знать, является ли это безопасным способом загрузки фото / гифок и видео.

if(isset($_POST['post'])) { $uploadOk = 1;
    $imageName = $_FILES['postToUpload']['name'];
    $errorMessage = ""; $picdate = date('Y-m-d_H-i-s');

    if($imageName != "") { $targetDir = "assets/images/posts/";
        $imageName = $targetDir . uniqid() . basename($imageName); $imageFileType = pathinfo($imageName, PATHINFO_EXTENSION); if($_FILES['postToUpload']['size'] > 10971520) {
            $errorMessage = "Your file is to large"; $uploadOk = 0;
        }

        if (strtolower($imageFileType) != "jpeg" && strtolower($imageFileType) != "png" &&
            strtolower($imageFileType) != "jpg" && strtolower($imageFileType) != "gif"
            && strtolower($imageFileType) != "mp4"&& strtolower($imageFileType) != "Ogg"
            && strtolower($imageFileType) != "WebM"){ $errorMessage = "File type not allowed.";
            $uploadOk = 0; } if($uploadOk){
            if(move_uploaded_file($_FILES['postToUpload']['tmp_name'], $imageName)) {
                // image uploaded

            } else{
                // image did not upload
                $uploadOk = 0; } } } if($uploadOk) {

    $post = new Post($con, $userLoggedIn); $post->submitPost(trim(strip_tags(filter_var($_POST['post_text'], FILTER_SANITIZE_STRING))), 'none', $imageName);

    } else {

        echo "<div class='alert alert-danger'>
                $errorMessage
            </div>";
    }
}

Ответы

2 Victor Sep 11 2020 at 20:56

Ваш код небезопасен, потому что:

  • Он полагается только на расширение файла, поэтому злоумышленники могут загружать любые бэкдоры.
  • Он обращается к переменной, $_FILES['postToUpload']['name']не проверяя, определена ли она, и это может привести к раскрытию полного пути.
  • Он использует функцию uniqid()без каких-либо аргументов, поэтому уникальность не гарантируется, а файлы, которые загружаются одновременно и имеют одинаковое имя, будут перезаписаны.
  • Он сохраняет имя файла, предоставленное пользователем, без удаления потенциально опасных символов, и это может привести к неожиданным результатам.

Некоторые рекомендации по улучшению вашего кода:

  • Избавьтесь от $uploadOkпеременной. У вас уже есть и обрабатывается $errorMessageпеременная, и этого достаточно, чтобы проверить, успешно ли был загружен файл.
  • Вы должны использовать $imageFileTypeстрочные буквы вместо вызова strtolower()каждого расширения.
  • Вы должны определить все допустимые расширения файлов в нижнем регистре, иначе пользователи не смогут загружать некоторые файлы (в вашем случае WebMи Ogg, потому что strtolower($imageFileType) != "Ogg"и strtolower($imageFileType) != "WebM"всегда будут FALSE).