В книге PHP глазами хакера есть ошибка. Для защиты от загрузки некорректных картинок я рекомендую использовать getimagesize. Этот момент был написан кажется ещё в первом издании и с тех пор я к нему не возвращался и не тестировал. Сейчас я полез в документацию и там к сожалению написано:
Caution
This function expects filename to be a valid image file. If a non-image file is supplied, it may be incorrectly detected as an image and the function will return successfully, but the array may contain nonsensical values.
Я быстро написал тестовый пример и действительно, для некорректного файла могут возвращаться мусорные данные, а значит защита с помощью getimagesize больше не сработает. Неожиданно. Когда я писал тот текст, то я его тестировал и на тот момент в PHP getimagesize падала при передаче неверных данных.
Вместо определения размера лучше пробовать загрузить картинку:
$gifimage = imagecreatefromgif($_FILES['file1']['tmp_name']);
if ($gifimage) {
if($_FILES['file1']['size']) {
move_uploaded_file($_FILES['file1']['tmp_name'], './filename.gif');
}
}
else {
echo 'Неверное изображение';
}
Сейчас проверил в последнем PHP8 и в этом случае проверка работает.
P.S. Сейчас проверил документацию по PHP 4 и 5 и там было написано:
Some formats may contain no image or may contain multiple images. In these cases, getimagesize() might not be able to properly determine the image size. getimagesize() will return zero for width and height in these cases.
Перевод:
Некоторые форматы могут не содержать изображений или содержать несколько изображений. В этих случаях getimagesize() не сможет правильно определить размер изображения. В этих случаях getimagesize() вернет ноль для ширины и высоты.
то есть тогда книга была корректная. Сейчас посмотрю, когда именно изменилось поведение. Но очень странно, что разработчики PHP в какой-то момент решили возвращать мусор вместо нулей. Судя по истории документации это произошло где-то в 2017-2018-м году, а я при написании последней версии книги я не проверил документацию. Это подстава! Вот почему говорят, не меняйте поведение функций, это ужас, такого делать нельзя, ведь это подстава для программистов.
Понравилось? Кликни Лайк, чтобы я знал, какой контент более интересен читателям. Заметку уже лайкнули 2 человек
А как быть в принципе, если это не картинка, а например мы даем юзерам загружать к примеру тот же .txt, а в нем будет <php ... получается выход только использование директив Apache? Т.е на уровне PHP нет инструмента определить соответствие содержимого файла его типу (расширению) ?
Даже imagecreatefromgif не даёт тебе полную гарантию, что файл корректный. Я для бусти записал уже видео и в пятницу или субботу оно будет опубликовано. Ты в другом комментарии ссылаешься на статью ch4inrulz, где основной причиной для взлома был всё же LFI. О нём я также уже говорил на бусти. Защищай от LFI, не давай TXT фалам выполнение на сервере и проблем не будет.
Хотите найти еще что-то интересное почитать? Можно попробовать отфильтровать заметки на блоге по категориям.