2009-11-02 2 views
1

Я использую язык PHP для загрузки файла и хочу знать, что следующий метод, который я использую, безопасен или нет?Безопасен ли этот способ загрузки файлов через PHP?

Я использую простой метод для загрузки файла, проверить имя файла из $ _FILES [ «UserFile»] [ «типа»] , а затем, если это имеющий разрешенное расширение файла, я загрузить файл с некоторыми случайными номер. Как будто это abc.zip, он может стать 8w43x9d.zip.

Скажите, пожалуйста, действительно ли это плохой способ для загрузки файлов?

ответ

2

Произвольно созданные безопасные имена файлов, безусловно, хорошо. Однако, если вы разрешаете расширение файла до webroot, вам все равно нужно убедиться, что расширение является чем-то, что не вызовет каких-либо проблем на сервере, например .php (ОК, обработка PHP должна быть отключена на веб-сервере для загружать каталоги, но все же). Существуют также проблемы, если вы находитесь на сервере Windows, где конечные точки и пробелы будут путать файловую систему; убедитесь, что вы заблокировали расширение до нескольких «известных хороших» значений.

К сожалению, собственность ['type'] не может положиться. Некоторые браузеры не будут заполнять тип содержимого, другие будут вводить неправильный тип, потому что их ОС настроены плохо (постыдно бесполезно, что IE по Windows по умолчанию вызывает JPEG image/pjpeg), некоторые всегда будут говорить application/octet-stream или даже text/plain ,

ID: ['name'] Недвижимость ненадежная; помимо браузеров, лежащих или обфускающих значение, всегда есть шанс, что данный тип будет иметь непредвиденное расширение файла на этой конкретной машине. Или, для клиентов Mac и Linux, вполне возможно, что загруженный файл вообще не будет иметь расширение (или может даже иметь неправильное расширение для того типа, который ОС видит в нем).

Так что да, это все немного беспорядок. В то время как обнюхивание для типа из представления Content-Type или расширения имени файла может быть полезно, чтобы угадать, какой тип файла по умолчанию должен быть, он абсолютно ненадежный, поэтому неплохо предоставить ручной метод для выбора типа файла. В качестве альтернативы, если вы загружаете загруженные файлы в виде вложений (например, с помощью PHP-скрипта Content-Disposition: attachment), вы можете часто уходить с простого вызова всего application/octet-stream и разрешать пользователю сортировать его, когда они его сохраняют.

Если вы не являетесь приложением, у вас может возникнуть проблема с безопасностью. IE с удовольствием понюхает многие типы файлов, которые вы обслуживаете для тегов <html>, и обрабатывайте эти файлы как HTML, даже если вы скажете, что они что-то другое.Затем он может отображать их inline в браузере и позволяет им вставлять скрипт в ваш контекст безопасности. Если у вас есть что-то существенное в вашем контексте безопасности, например учетные записи пользователей и куки-файлы, это дыра безопасности для межсайтового скриптинга. Обходные пути для этого служат вложением и/или служением из другого имени хоста, которое не находится в контексте безопасности вашего основного сайта (обычно используется субдомен).

Разрешить пользователям, которым вы не доверяете полностью загружать файлы на свой сервер, оказывается на самом деле гораздо более сложной задачей, чем тривиальный пример кода в учебниках PHP заставит вас поверить. :-(

1

От PHP Manual:

$ _FILES [ 'UserFile'] [ 'типа']

Тип мим файла, если браузер предоставил эту информацию. Примером может служить «image/gif». Этот тип mime, однако, не проверяется на стороне PHP и поэтому не принимает его значение как должное.

я бы не доверять чему-либо пользователю или браузер пользователя отправляет меня.

Если вы пытаетесь учиться, я бы посмотрел на существующие безопасные источники, такие как HTTP_Upload от PEAR. Вы даже можете рассмотреть возможность использования бета-версии.

+1

спасибо за это, но ваша ссылка дает 404 не найдена ошибка! – user153887

+0

работает для меня ... работает без префикса 'ca2.', также. Ссылка * не * сломана, она может быть заблокирована в конце. – pavium

+0

Ссылка PEAR 404 для m e также. –

0

Дополнения к посту выше, мы полагаемся на FileInfo или SplFileInfo, до сих пор она оказалась наилучшим вариантом для наших нужд.

0

OK, в случае изображений, которые мы можем использовать getimagesize($_FILES['userfile']['tmp_name']); и может проверить их, но что в случае ZIP, RAR и PDF файлы?

Смежные вопросы