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


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

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

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

 21
Author: halfer, 2012-06-16

4 answers

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

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

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

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

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

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

  3. Никогда никому и ничему не позволяйте произвольно обращаться к файлу. Например, если злоумышленник загружает файл malicious.php на ваш сервер, и вы сохраняете его в каталоге webroot вашего сайта, пользователь может просто перейти к example.com/uploads/malicious.php, чтобы выполнить этот файл и запустить произвольный PHP-код на вашем сервере.

    • Никогда не храните произвольно загруженные файлы в любом публичном месте всегда храните их там, где только ваше приложение имеет к ним доступ.

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

    • Если вы не знаете, с каким типом файла имеете дело, определите тип MIME файла самостоятельно и/или попробуйте разрешить определенному процессу открыть файл (например, позвольте процессу изменения размера изображения попытаться изменить размер предполагаемого изображения). Будьте осторожны и здесь, если в этом процессе есть уязвимость, злонамеренно созданный файл может использовать ее, что может привести к нарушениям безопасности (наиболее распространенный пример такого атаки - это программа чтения PDF от Adobe).


Чтобы ответить на ваши конкретные вопросы:

[Чтобы проверить даже размер этих изображений, я должен хранить их в своей папке /tmp. Разве это не рискованно?

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

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

Что, если шутник даст мне URL-адрес, и я в конечном итоге скачаю весь веб-сайт, полный вредоносных программ?

Вам решать, что именно вы загружаете. Один URL-адрес приведет не более чем к одному большому двоичному объекту данных. Если вы анализируете эти данные и загружаете содержимое большего количества URL-адресов на основе этого начального большого двоичного объекта, это ваша проблема. Не делай этого. Но даже если бы вы это сделали, что ж, тогда у вас был бы временный каталог, полный всякой всячины. Опять же, это не опасно, если вы не делаете ничего опасного с этим материалом.

 32
Author: deceze, 2012-06-16 11:28:34

1 простой сценарий будет : Если вы используете интерфейс загрузки, в котором нет ограничений на тип файлов, разрешенных для загрузки, злоумышленник может загрузить файл PHP или .NET с вредоносным кодом, который может привести к компрометации сервера.

См.: http://www.acunetix.com/websitesecurity/upload-forms-threat.htm По ссылке выше обсуждаются общие проблемы

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

 5
Author: mithunsatheesh, 2012-06-16 06:38:15

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

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

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

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

 3
Author: hjpotter92, 2012-06-16 06:32:38

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

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

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

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

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

 3
Author: Dmitry Evseev, 2012-06-16 08:00:38