Безопасные возможности загрузки изображений в PHP - PullRequest
10 голосов
/ 05 сентября 2010

Я использую инструмент загрузки изображений для моего сайта.Система должна позволять любым пользователям загружать только файлы JPEG и PNG.Я, конечно, беспокоюсь о безопасности, и поэтому мне интересно, что многие умные люди, чем я, чувствуют по поводу следующих проверок для разрешения загрузки:

1) Сначала внесите белый список в список допустимых расширений файлов в PHP дляразрешить только PNG, PNG, JPG, JPG и JPEG.Получить расширение файла пользователя можно с помощью такой функции, как:

return end(explode(".", $filename));

Это должно помочь запретить пользователю загружать что-либо вредоносное, например, .png.php.Если это пройдет, перейдите к шагу 2.

2) Запустите функцию php getimageize () для файла TMP.Через что-то вроде:

getimagesize($_FILES['userfile']['tmp_name']);

Если это не возвращает false, продолжайте.

3) Убедитесь, что файл .htaccess размещен в каталоге загрузки, чтобы любые файлы в этом каталоге не могли быть проанализированыФайлы PHP:

php_admin_value engine Off

4) Переименуйте файл пользователя во что-то заранее определенное.IE

$filename = 'some_pre_determined_unique_value' . $the_file_extension;

Это также поможет предотвратить внедрение SQL, поскольку имя файла будет единственной определяемой пользователем переменной в любых используемых запросах.

Если я выполню вышеизложенное, насколько уязвим для атаки яЯ по-прежнему?Прежде чем принять файл, я надеюсь, что я должен: 1) разрешить только jpgs и pngs, 2) проверить, что PHP говорит, что это правильный образ, 3) отключить каталог, в котором находятся изображения, от выполнения файлов .php, и 4) переименовать файл пользователя в нечтоуникальный.

Спасибо,

Ответы [ 3 ]

20 голосов
/ 05 сентября 2010

Что касается имен файлов, случайные имена, безусловно, являются хорошей идеей и снимают много головной боли.

Если вы хотите полностью убедиться, что содержимое чистое, рассмотрите возможность использования GD или ImageMagick для копирования входящего изображения.1: 1 в новый, пустой.

Это немного ухудшит качество изображения, поскольку содержимое сжимается дважды, но удаляет любую EXIF-информацию, присутствующую в исходном изображении.Пользователи часто даже не знают, сколько информации попадает в раздел метаданных файлов JPG!Информация о камере, положение, время, используемое программное обеспечение ... Это хорошая политика для сайтов, на которых размещены изображения, для удаления этой информации для пользователя.

Кроме того, копирование изображения, вероятно, избавит от большинства эксплойтов, использующих неисправное изображениеданные вызывают переполнение в программном обеспечении для просмотра и вводят вредоносный код.Такие манипулируемые изображения, вероятно, просто окажутся нечитаемыми для GD.

4 голосов
/ 05 сентября 2010

Относительно вашего номера 2), не просто проверяйте на FALSE.getimagesize также возвращает тип изображения mime.Это гораздо более безопасный способ проверки правильного типа изображения, чем просмотр MIME-типа, предоставляемого клиентом:

$info = getimagesize($_FILES['userfile']['tmp_name']);
if ($info === FALSE) {
    die("Couldn't read image");
}
if (($info[2] !== IMAGETYPE_PNG) && ($info[2] !== IMAGETYPE_JPEG)) {
    die("Not a JPEG or PNG");
}
1 голос
/ 05 сентября 2010

Все проверки кажутся хорошими, особенно номер 3.Если производительность не является проблемой, или вы делаете это в фоновом режиме, вы можете попробовать получить доступ к изображению с помощью GD и посмотреть, действительно ли это изображение, а не просто чепуха, которой кто-то пытается заполнить ваш сервер.

...