Ответ 1
Прежде всего, убедитесь, что загрузка файла означает, что пользователь предоставляет вам много данных в различных форматах и что пользователь имеет полный контроль над этими данными. Это даже проблема для текстового поля нормальной формы, загрузка файлов одинакова и намного больше. Первое правило: Не доверяйте никому из них.
Что вы получаете от пользователя с загрузкой файла:
- данные файла
- имя файла
- тип MIME
Это три основных компонента загрузки файла, и ни одна из них не является надежной.
-
Не доверяйте типу MIME в
$_FILES['file']['type']
. Это абсолютно произвольное значение, предоставленное пользователем. -
Не используйте имя файла для чего-либо важного. Это совершенно произвольное, поставленное пользователем значение. Вы не можете доверять расширению файла или имени в целом. Не сохраняйте файл на жестком диске сервера, используя что-то вроде
'dir/' . $_FILES['file']['name']
. Если имя'../../../passwd'
, вы переписываете файлы в других каталогах. Всегда создавайте случайное имя самостоятельно, чтобы сохранить файл как. Если вы хотите, вы можете сохранить исходное имя файла в базе данных в виде метаданных. -
Никогда не позволяйте никому или чему-либо обращаться к файлу произвольно. Например, если злоумышленник загружает файл
malicious.php
на ваш сервер и вы храните его в каталоге webroot вашего сайта, пользователь может просто перейти кexample.com/uploads/malicious.php
, чтобы выполнить этот файл и выполнить произвольный PHP-код на вашем сервере.-
Никогда не храните произвольные загруженные файлы в любом месте публично, всегда храните их где-нибудь, где только ваше приложение имеет к ним доступ.
-
Разрешать доступ к файлам только определенным процессам. Если он должен быть файлом изображения, разрешите script читать изображения и изменять их размеры для прямого доступа к файлу. Если этот script имеет проблемы с чтением файла, он, вероятно, не является файлом изображения, отметьте его и/или отмените. То же самое касается других типов файлов. Если файл должен быть загружен другими пользователями, создайте script, который загрузит файл для загрузки и ничего не сделает с ним.
-
Если вы не знаете, с каким типом файлов вы сталкиваетесь, определите тип файла MIME самостоятельно и/или попробуйте разрешить определенному процессу открыть файл (например, пусть процесс изменения размера изображения пытается изменить размер предполагаемого изображения). Также будьте осторожны, если есть уязвимость в этом процессе, вредоносный файл может использовать его, что может привести к нарушениям безопасности (наиболее распространенным примером таких атак является Adobe PDF Reader).
-
Чтобы ответить на ваши конкретные вопросы:
[T] o проверьте размер этих изображений, которые я должен хранить в папке /tmp. Разве это не рискованно?
Нет. Простое хранение данных в файле во временной папке не является рискованным, если вы ничего не делаете с этими данными. Данные - это просто данные, независимо от их содержимого. Это только опасно, если вы пытаетесь выполнить данные или если программа анализирует данные, которые могут быть обмануты, чтобы делать неожиданные вещи по вредоносным данным, если программа содержит разбор ошибок.
Конечно, наличие каких-либо вредоносных данных, сидящих на диске, более рискованно, чем отсутствие вредоносных данных в любом месте. Вы никогда не знаете, кто придет и что-то с этим поделает. Поэтому вы должны проверить любые загруженные данные и отбросить их как можно скорее, если они не пройдут проверку.
Что, если шутник дает мне URL-адрес, и я в конечном итоге загружаю весь сайт, полный вредоносного ПО?
Это вам, что именно вы загружаете. Один URL-адрес приведет к лучшему в одном блоке данных. Если вы разбираете эти данные и загружаете содержимое большего количества URL-адресов на основе этого начального блоба, что ваша проблема. Не делай этого. Но даже если бы вы это сделали, ну, тогда у вас будет каталог temp, полный материалов. Опять же, это не опасно, если вы не делаете ничего опасного в этом случае.