#php
#php
Вопрос:
Я написал php-скрипт, который проверяет файл изображения на его расширение, такое как JPG, JPEG, PNG, GIF, загруженный через HTML-форму.
Теперь возникает моя проблема: любой может загрузить файл любого типа, присвоив ему расширение JPG, JPEG, PNG, GIF.
Кто-нибудь может мне помочь в этом? Строго говоря, должна быть возможность загружать только файл изображения, а не любой другой файл, который имеет только расширение файла изображения.
Я очень старался… но не удалось… Вот написанный мной php-скрипт ПРОВЕРЬТЕ мой ПОЛНЫЙ КОД, который я НАПИСАЛ, И ОН РАБОТАЕТ НОРМАЛЬНО, НО КОГДА я МЕНЯЮ РАСШИРЕНИЕ ЛЮБОГО ФАЙЛА На РАСШИРЕНИЕ ИЗОБРАЖЕНИЯ, РАЗРЕШАЮЩЕЕ ЗАГРУЗКУ На СЕРВЕР, КОТОРЫЙ НЕ ЯВЛЯЕТСЯ SERCURE ПОЖАЛУЙСТА, ПОСМОТРИТЕ этот ПОЛНЫЙ КОД И ДОБАВЬТЕ РЕШЕНИЕ, ЭТО ТОЖЕ ПОМОЖЕТ ДРУГИМ — СПАСИБО https://www.dropbox.com/s/prza75dyo7usjqy/secure image upload with checking extension.txt?dl=0
if (isset($_POST['submit']))
$filename = $_FILES["file"]["name"];
$file_basename = substr($filename, 0, strripos($filename, '.')); // get file extention
$file_ext = substr($filename, strripos($filename, '.')); // get file name
$filesize = $_FILES["file"]["size"];
$allowed_file_types = array('.jpg','.png','.jpeg','.gif');
//instead of allowed file type i want to check image authenticity with MIME
if (in_array($file_ext,$allowed_file_types) amp;amp; ($filesize < 100000))
Ответ №1:
Вам следует использовать fileinfo API, который позволяет вам проверять тип содержимого файла MIME, просматривая его байты, а не его имя.
Тип MIME изображения всегда начинается с image/
, например image/png
.
$finfo = new finfo();
$mimeType = $finfo->file($_FILES['file']['tmp_name'], FILEINFO_MIME_TYPE);
$isImage = strpos($mimeType, 'image/') === 0;
Если вы хотите строго ограничить разрешенные изображения, проверьте список доступных типов MIME.
Редактировать: быть более конкретным
if (isset($_POST['submit'])) {
$filename = $_FILES["file"]["tmp_name"];
$filesize = $_FILES["file"]["size"];
$allowed_file_types = array('image/jpeg','image/png','image/gif');
$finfo = new finfo();
$mimeType = $finfo->file($filename, FILEINFO_MIME_TYPE);
$isImage = in_array($mimeType, $allowed_file_types);
if ($isImage amp;amp; $filesize < 100000) {
Комментарии:
1. Пожалуйста, ответьте в контексте приведенного выше кода, как я могу применить этот код к верхнему, пожалуйста, укажите
2. Я отредактировал его. Обратите внимание, что я использую
tmp_name
ключ для извлечения имени файла на стороне сервера, а неname
на стороне клиента.3. сэр, не работает, проверьте мой полный код и добавьте к нему решение dropbox.com/s/prza75dyo7usjqy /…
4. надеюсь, ты шутишь, приятель 🙂 я здесь не для того, чтобы выполнять твою работу. Этот фрагмент кода работает , даже если вы говорите, что это не так. Помните, когда вы просили меня указать ?
Ответ №2:
Самый безопасный способ проверить, является ли что-то действительно изображением, — это открыть файл как изображение, а затем повторно сгенерировать его.
Вещи, которые являются допустимыми изображениями, все еще могут содержать множество другой информации и иногда могут обмануть то, что ее читает. Итак, самая безопасная вещь — это взять пиксели из изображения и восстановить его.
Такие расширения, как fileinfo
, проверяют маркер только в первых нескольких байтах, но это не на 100% надежно. Для вас этого может быть достаточно
Комментарии:
1. Я колебался между моим текущим ответом и другим, похожим на ваши шаги, с
Imagick
API, но поскольку мне кажется, что это вопрос для начинающих и учитывая крошечный размерfileinfo
по сравнению сImagick
, я выбралfileinfo
.2. @rugolinifr да, я подумал, что это хороший вопрос, на который может быть 2 правильных ответа =)