Я разрешаю пользователям загружать файлы на мой сервер. С какими возможными угрозами безопасности я сталкиваюсь и как их устранить?
Предположим, я разрешаю пользователям загружать изображения на мой сервер либо из их системы, либо из сети. Теперь, чтобы проверить размер этих изображений, я должен хранить их в папке /tmp
. Разве это не рискованно? Как я могу свести к минимуму риск?
Также предположим, что я использую wget
для загрузки изображений из ссылки, которую пользователи загружают в мою форму. Сначала я должен сохранить эти файлы на своем сервере, чтобы проверить, действительно ли они являются изображениями. И что, если шутник дает мне URL-адрес, и я в конечном итоге загружаю весь сайт, полный вредоносного ПО?
Прежде всего, поймите, что загрузка файла означает, что пользователь предоставляет вам много данных в различных форматах и что пользователь имеет полный контроль над этими данными. Это даже проблема для текстового поля нормальной формы, загрузка файлов одинакова и намного больше. Первое правило: Не доверяйте ни одному из них.
Что вы получаете от пользователя с загрузкой файла:
Это три основных компонента загрузки файлов, и ни одна из них не является надежной.
Не доверяйте типу MIME в $_FILES['file']['type']
. Это совершенно произвольная, поставляемая пользователем стоимость.
Не используйте имя файла для чего-либо важного. Это совершенно произвольная, поставляемая пользователем стоимость. Вы не можете доверять расширению файла или имени в целом. Не сохраняйте файл на жестком диске сервера, используя что-то вроде 'dir/' . $_FILES['file']['name']
'dir/' . $_FILES['file']['name']
. Если имя '../../../passwd'
, вы переписываете файлы в другие каталоги. Всегда создавайте случайное имя самостоятельно, чтобы сохранить файл как. Если вы хотите, вы можете сохранить исходное имя файла в базе данных в виде метаданных.
Никогда не позволяйте никому или чему-либо доступ к файлу произвольно. Например, если злоумышленник загружает файл malicious.php
на ваш сервер, и вы храните его в каталоге webroot вашего сайта, пользователь может просто перейти на example.com/uploads/malicious.php
чтобы выполнить этот файл и запустить произвольный PHP-код на вашем сервере.
Никогда не храните произвольные загруженные файлы в любом месте публично, всегда храните их где-нибудь, где только ваше приложение имеет к ним доступ.
Разрешать доступ к файлам только определенным процессам. Если он должен быть файлом изображения, разрешите только сценарий, который читает изображения и изменяет их размеры для прямого доступа к файлу. Если у этого скрипта есть проблемы с чтением файла, это, вероятно, не файл изображения, отметьте его и / или отбросите. То же самое касается других типов файлов. Если файл должен быть загружен другими пользователями, создайте скрипт, который загрузит файл для загрузки и ничего не сделает с ним.
Если вы не знаете, с каким типом файлов вы сталкиваетесь, определите тип MIME файла самостоятельно и / или попробуйте разрешить определенному процессу открыть файл (например, пусть процесс изменения размера изображения попытается изменить размер предполагаемого изображения). Также будьте осторожны, если в этом процессе есть уязвимость, вредоносный файл может использовать его, что может привести к нарушениям безопасности (наиболее распространенным примером таких атак является Adobe Reader Reader Adobe).
Чтобы ответить на ваши конкретные вопросы:
[T] o проверьте даже размер этих изображений, которые я должен хранить в папке / tmp. Разве это не рискованно?
Нет. Просто хранить данные в файле во временной папке не рискованно, если вы ничего не делаете с этими данными. Данные – это просто данные, независимо от их содержимого. Это всего лишь рискованно, если вы пытаетесь выполнить данные или если программа анализирует данные, которые могут быть обмануты в непредвиденные ситуации вредоносными данными, если программа содержит разбор ошибок.
Конечно, наличие каких-либо вредоносных данных, сидящих на диске, более рискованно, чем отсутствие вредоносных данных в любом месте. Вы никогда не знаете, кто придет и что-то с этим поделает. Поэтому вы должны проверить любые загруженные данные и отбросить их как можно скорее, если они не пройдут проверку.
Что, если шутник дает мне URL-адрес, и я в конечном итоге загружаю весь сайт, полный вредоносного ПО?
Это зависит от вас, что именно вы загружаете. Один URL-адрес приведет к лучшему в одном блоке данных. Если вы разбираете эти данные и загружаете содержимое большего количества URL-адресов на основе этого начального блоба, это ваша проблема. Не делай этого. Но даже если бы вы это сделали, ну, тогда у вас будет каталог temp, полный материалов. Опять же, это не опасно, если вы не делаете ничего опасного в этом.
1 простой сценарий будет: если вы используете интерфейс загрузки, где нет ограничений на тип файлов, разрешенных для загрузки, злоумышленник может загрузить PHP или файл .NET с помощью вредоносного кода, который может привести к компрометации сервера.
см. http://www.acunetix.com/websitesecurity/upload-forms-threat.htm. В приведенной выше ссылке обсуждаются общие проблемы
Вот некоторые из них:
Когда файл загружается на сервер, PHP будет устанавливать переменную $ _FILES ['uploadedfile'] ['type'] на mime-тип, предоставляемый веб-браузером, который использует клиент. Однако проверка формы загрузки файлов не может зависеть только от этого значения. Злоумышленник может легко загружать файлы с помощью сценария или другого автоматизированного приложения, которое позволяет отправлять запросы HTTP POST, которые позволяют ему отправлять поддельный тип mime.
Почти невозможно составить список, содержащий все возможные расширения, которые может использовать злоумышленник. Например, если код работает в размещенной среде, обычно такие среды допускают большое количество языков сценариев, таких как Perl, Python, Ruby и т. Д., И список может быть бесконечным.
Злоумышленник может легко обойти такую проверку, загрузив файл под названием «.htaccess», который содержит строку кода, аналогичную приведенной ниже:
AddType application/x-httpd-php .jpg
Существуют общие правила, позволяющие избежать общих проблем с загрузкой файлов:
Чтобы избежать проблем с файловой системой в случае, если в папке / var / uploads слишком много файлов, рассмотрите возможность хранения файлов в дереве папок следующим образом:
file hash = 234wffqwdedqwdcs
-> хранить его в /var/uploads/23/234wffqwdedqwdcs
общее правило: /var/uploads/<first 2 hash letters>/<hash>
установите nginx, если вы еще не сделали его – он служит статичным, как магия, и его заголовок «X-Accel-Redirect» позволит вам обслуживать файлы с разрешениями, которые сначала проверяются пользовательским скриптом