Защита файлов на сайте PHP - PullRequest
3 голосов
/ 07 марта 2011

У меня есть сайт, который принимает загруженные пользователем файлы (изображения, PDF-файлы, документы Word и т. Д.), А затем позволяет другим пользователям загружать их.

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

У меня такой вопрос - достаточно ли проверить тип пантомимызагружать файл с помощью PHP (mime_content_type или finfo) и устанавливать для него файл только для чтения (не исполняемый), или я должен также сохранять загруженные файлы в каталоге, который находится за пределами корневого веб-каталога?Я думаю, что это устранит большую часть риска из загруженного файла, но я не уверен.В этой ситуации невозможно выполнить проверку на вирусы для загруженных файлов.

Спасибо за ввод.

Ответы [ 3 ]

1 голос
/ 07 марта 2011

Я бы проверил MIME-тип файла, но я бы на это не полагался.Даже если файл является полноценным .gif и содержит комментарий в своем теге id3, который является php, он может быть выполнен с локальным файлом, включая .Более безопасный подход - хранить файлы в базе данных, используя тип данных long blob.Однако этот вид накладных расходов - дерьмо.

Наилучшим решением с точки зрения безопасности, масштабируемости и производительности было бы использование базы данных no-sql, такой как CouchDB.

Несколько вещей, о которых следует помнить,не верь $_FILES[].$_FILES['type'] может быть тем, что хочет атакующий, поэтому нет смысла проверять его с точки зрения безопасности.И $_FILES['name'] может иметь неприятные данные, такие как ../../../.Лучше всего переименовать файлы в первичный ключ, а затем сохранить информацию об этом файле в реляционной базе данных (например, mysql).

1 голос
/ 07 марта 2011

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

Лучше всего, чтобы файлы были загружены на другой сервер .Тот, который может содержать только файлы.

1 голос
/ 07 марта 2011

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

Fileinfo finfo_ полезно для проверки большинства типов mimety, по крайней меречтобы убедиться, что то, что называется ".txt", на самом деле является текстовым файлом, а не двоичным двоичным объектом, или что ".jpg" действительно является jpeg на основе его первых или последних нескольких байтов.Это может потребовать дополнительной работы по сортировке mimetypes MS Office, так как, если я правильно помню, все они выглядят как application-msword.Но затем вы можете использовать расширение файла, чтобы выяснить, каким оно действительно должно быть (xls, ppt, doc и т. Д.).

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

header("Content-type: application-whatever");
header("Content-length: size-of-the-file-in-bytes");
...