Угрозы безопасности с загрузками

Я разрешаю пользователям загружать файлы на мой сервер. С какими возможными угрозами безопасности я сталкиваюсь и как их устранить?

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

Также предположим, что я использую wget для загрузки изображений из ссылки, которую пользователи загружают в мою форму. Сначала я должен сохранить эти файлы на своем сервере, чтобы проверить, действительно ли они являются изображениями. И что, если шутник дает мне URL-адрес, и я в конечном итоге загружаю весь сайт, полный вредоносного ПО?

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

Что вы получаете от пользователя с загрузкой файла:

  • данные файла
  • имя файла
  • тип MIME

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

  1. Не доверяйте типу MIME в $_FILES['file']['type'] . Это совершенно произвольная, поставляемая пользователем стоимость.

  2. Не используйте имя файла для чего-либо важного. Это совершенно произвольная, поставляемая пользователем стоимость. Вы не можете доверять расширению файла или имени в целом. Не сохраняйте файл на жестком диске сервера, используя что-то вроде 'dir/' . $_FILES['file']['name'] 'dir/' . $_FILES['file']['name'] . Если имя '../../../passwd' , вы переписываете файлы в другие каталоги. Всегда создавайте случайное имя самостоятельно, чтобы сохранить файл как. Если вы хотите, вы можете сохранить исходное имя файла в базе данных в виде метаданных.

  3. Никогда не позволяйте никому или чему-либо доступ к файлу произвольно. Например, если злоумышленник загружает файл 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. В приведенной выше ссылке обсуждаются общие проблемы

также см. http://php.net/manual/en/features.file-upload.php

Вот некоторые из них:

  • Когда файл загружается на сервер, PHP будет устанавливать переменную $ _FILES ['uploadedfile'] ['type'] на mime-тип, предоставляемый веб-браузером, который использует клиент. Однако проверка формы загрузки файлов не может зависеть только от этого значения. Злоумышленник может легко загружать файлы с помощью сценария или другого автоматизированного приложения, которое позволяет отправлять запросы HTTP POST, которые позволяют ему отправлять поддельный тип mime.

  • Почти невозможно составить список, содержащий все возможные расширения, которые может использовать злоумышленник. Например, если код работает в размещенной среде, обычно такие среды допускают большое количество языков сценариев, таких как Perl, Python, Ruby и т. Д., И список может быть бесконечным.

    Злоумышленник может легко обойти такую ​​проверку, загрузив файл под названием «.htaccess», который содержит строку кода, аналогичную приведенной ниже: AddType application/x-httpd-php .jpg

Существуют общие правила, позволяющие избежать общих проблем с загрузкой файлов:

  • Храните загруженные файлы не в корневой папке вашего сайта, поэтому пользователи не смогут перезаписывать ваши файлы приложений и напрямую получать доступ к загружаемым файлам (например, в / var / uploads, когда ваше приложение находится в / var / www ).
  • Сохранение имен санированных файлов в базе данных и физических файлах дает имя хеш-значения файла (это также устраняет проблему хранения дубликатов файлов – они будут иметь равные хэши).
  • Чтобы избежать проблем с файловой системой в случае, если в папке / var / uploads слишком много файлов, рассмотрите возможность хранения файлов в дереве папок следующим образом:

    file hash = 234wffqwdedqwdcs -> хранить его в /var/uploads/23/234wffqwdedqwdcs

    общее правило: /var/uploads/<first 2 hash letters>/<hash>

  • установите nginx, если вы еще не сделали его – он служит статичным, как магия, и его заголовок «X-Accel-Redirect» позволит вам обслуживать файлы с разрешениями, которые сначала проверяются пользовательским скриптом