Подход безопасности загрузки изображений PHP - PullRequest
12 голосов
/ 06 сентября 2011

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

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

  1. Фотография загружена в личную папку 777 вне корневого веб-каталога.
  2. Выполняется проверка расширений из белого списка (разрешены только jpgs, gifs, pngs) все остальное удаляется.
  3. Использование getimagesize для проверки минимальных размеров и достоверности фотографий.
  4. Проверка соответствия mimetype и расширения файла.
  5. Изменение размера загруженной фотографии до стандартных размеров (с использованием imagecopyresampled).
  6. Сохранение созданных файлов в формате jpg.
  7. Удаление исходного файла.
  8. Сохранение фотографий с новым (не случайным)name) ie img51244.jpg.
  9. Переместить новые фотографии в переменные подкаталоги общей папки (777 разрешений) в соответствии с непредсказуемым алгоритмом.Т.е. img10000.jpg будет храниться в photos/a/f/0/img10000.jpg, а img10001.jpg будет храниться в photos/0/9/3/img10001.jpg.Это делается по другим причинам (использование поддоменов для обслуживания статического содержимого или использование CDN).

Сценарий будет работать на выделенном сервере Linux.

Ответы [ 3 ]

4 голосов
/ 06 сентября 2011
  1. Каталог с chmod 0777, по определению, является общедоступным для других пользователей, вошедших на ваш сервер, а не закрытым. Правильные разрешения равны 700 и принадлежат apache (или любому пользователю, на котором работает ваш веб-сервер). Я не уверен, почему бы вам не использовать временный каталог по умолчанию в php, поскольку он, как правило, также находится вне корневого веб-каталога.
  2. Белый список - хорошая идея. Будьте осторожны, чтобы иметь правильную реализацию. Например, регулярное выражение /.png/ фактически соответствует apng.php.
  3. Этот шаг - отличная идея. Это в основном проверяет магию файла.
  4. Не является строго обязательным. На двух предыдущих шагах мы определили, что расширение и формат файла верны. Если вам требуется, чтобы клиент указывал правильный тип MIME, вам также следует проверить, что данный тип MIME и тот, который определен выше, эквивалентны.

Шаги с 5 по 8 не связаны с безопасностью.

Шаг 9: Я предполагаю, что ваш сайт позволяет всем видеть каждую фотографию. Если это не так, у вас должна быть схема URL со значительно более длинными URL (например, хэш-сумма изображения).

3 голосов
/ 06 сентября 2011

Вы также должны проверить размер загружаемого файла, так как getimagesize может иногда превышать доступную оперативную память. Также полезно предположить, что ваш сценарий может дать сбой в любой момент (например, при отключении электричества), поэтому вы должны выполнить некоторые процедуры очистки для удаления левых, ненужных файлов.

0 голосов
/ 06 сентября 2011

Это довольно полный подход, но я не вижу никакого механизма предотвращения выполнения кода.

Вы должны убедиться, что содержимое изображения никогда не включается (с помощью вызова include или require) или выполняется через eval ().

В противном случае может быть выполнен php-код, включенный в конец файла.

Вы также можете попытаться обнаружить php-код внутри содержимого изображения (с помощью file_get_contents, а затем выполнить поиск по регулярному выражению для "<? php ", например), но я не смог найти 100% безопасный способ устранения подозрительного кода без уничтожения некоторых (действительных) изображений. </p>

...